home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume13 / jetpack / part03 < prev    next >
Encoding:
Internet Message Format  |  1992-04-09  |  54.6 KB

  1. Path: uunet!spool.mu.edu!uwm.edu!ogicse!zephyr.ens.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v13i075:  jetpack - an arcade action game for X, Part03/04
  5. Message-ID: <2647@master.CNA.TEK.COM>
  6. Date: 23 Mar 92 22:32:04 GMT
  7. Article-I.D.: master.2647
  8. Sender: news@master.CNA.TEK.COM
  9. Lines: 2104
  10. Approved: billr@saab.CNA.TEK.COM
  11.  
  12. Submitted-by: meb2@cec2.wustl.edu (Mark Edward Bradley)
  13. Posting-number: Volume 13, Issue 75
  14. Archive-name: jetpack/Part03
  15. Environment: X11, Xlib
  16.  
  17.  
  18.  
  19. #! /bin/sh
  20. # This is a shell archive.  Remove anything before this line, then unpack
  21. # it by saving it into a file and typing "sh file".  To overwrite existing
  22. # files, type "sh file -c".  You can also feed this as standard input via
  23. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  24. # will see the following message at the end:
  25. #        "End of archive 3 (of 4)."
  26. # Contents:  Makefile.simple defs.h demo.c erase.c initx.c maze.c
  27. #   normal.c setup.c update.c
  28. # Wrapped by billr@saab on Mon Mar 23 14:29:27 1992
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'Makefile.simple' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'Makefile.simple'\"
  32. else
  33. echo shar: Extracting \"'Makefile.simple'\" \(1239 characters\)
  34. sed "s/^X//" >'Makefile.simple' <<'END_OF_FILE'
  35. X# Program name
  36. XEXEC = jetpack
  37. X
  38. X# Master destination directory
  39. XDESTDIR = /usrd/s/m/meb2
  40. X
  41. X# Various subdirectories
  42. XLIBDIR = $(DESTDIR)/lib/jetpack
  43. XBINDIR = $(DESTDIR)/bin
  44. XMANPATH = $(DESTDIR)/man
  45. X
  46. X# Files for high scores and predifined levels
  47. XSCOREFILE = $(LIBDIR)/jetpack.scores
  48. XLEVELFILE = $(LIBDIR)/jetpack.lev
  49. X
  50. X# -O4 for optimization, -DBLIT for blitting
  51. XCFLAGS = -O4 -DBLIT -DSCOREPATH=\"$(SCOREFILE)\" -DLEVELPATH=\"$(LEVELFILE)\"
  52. X
  53. X# Your favorite X library
  54. XLIBS = -lX11
  55. X
  56. XOBJS =    bitmap.o bonus.o collision.o demo.o draw.o erase.o events.o\
  57. X        gameover.o initx.o main.o maze.o message.o normal.o quitx.o\
  58. X        scores.o setinmaze.o setup.o special.o time.o update.o windowx.o
  59. X
  60. Xjetpack: $(OBJS)
  61. X    cc -o $(EXEC) $(OBJS) $(LIBS) $(CFLAGS)
  62. X
  63. X# do whatever you like for installation here. I have it set all the data
  64. X# files to be readable and writable only by the user, (except the man
  65. X# page) and the program itself to be setuid
  66. Xinstall: $(EXEC)
  67. X    strip $(EXEC)
  68. X    cp $(EXEC) $(BINDIR)
  69. X    chmod 4755 $(BINDIR)/$(EXEC)
  70. X    cp levels/000 $(LEVELFILE)000
  71. X    chmod 0600 $(LEVELFILE)000
  72. X    cp jetpack.man $(MANDIR)/jetpack.n
  73. X    chmod 0644 $(MANDIR)/jetpack.n
  74. X
  75. X# dependencies (leave these alone)
  76. X$(OBJS) : defs.h copyright.h
  77. Xbitmap.o : bitmap.h
  78. Xmessage.c : message.h
  79. END_OF_FILE
  80. if test 1239 -ne `wc -c <'Makefile.simple'`; then
  81.     echo shar: \"'Makefile.simple'\" unpacked with wrong size!
  82. fi
  83. # end of 'Makefile.simple'
  84. fi
  85. if test -f 'defs.h' -a "${1}" != "-c" ; then 
  86.   echo shar: Will not clobber existing file \"'defs.h'\"
  87. else
  88. echo shar: Extracting \"'defs.h'\" \(6636 characters\)
  89. sed "s/^X//" >'defs.h' <<'END_OF_FILE'
  90. X/*    defs.h : externally defined things for jetpack
  91. X*/
  92. X
  93. X#include "copyright.h"
  94. X
  95. X/*    here are all the include files used by the different source files.
  96. X    Since every source file includes this one, it makes dependencies a lot
  97. X    more efficient.
  98. X*/
  99. X
  100. X#include    <stdio.h>
  101. X#include    <string.h>
  102. X#include    <fcntl.h>
  103. X#include    <sys/param.h>
  104. X#include    <sys/file.h>
  105. X#include    <sys/types.h>
  106. X#include    <sys/time.h>
  107. X#include    <X11/Xlib.h>
  108. X#include    <X11/Xutil.h>
  109. X#include    <X11/keysym.h>
  110. X#include    <X11/keysymdef.h>
  111. X
  112. X/*    Windowing stuff
  113. X*/
  114. X
  115. X/*    Dimensions of the window and the information window
  116. X*/
  117. X#define WINDOWWIDTH        500
  118. X#define WINDOWHEIGHT    500
  119. X#define INFOHEIGHT        50
  120. X
  121. X/*    Error factor used in non-blitting version for overlap testing.
  122. X*/
  123. X#ifdef    BLIT
  124. X#define    EDGE    0
  125. X#else
  126. X#define    EDGE    10
  127. X#endif
  128. X
  129. X/*    Definitions for erase zone types.
  130. X*/
  131. X#define    ZLINE        0
  132. X#define    ZPLAYER        1
  133. X#define    ZBURN        2
  134. X#define    ZEXPLODE    3
  135. X#define    ZFIRE        4
  136. X#define    ZGUARD        5
  137. X#define    ZSWEEP        6
  138. X#define    ZFUEL        7
  139. X#define    ZKEY        8
  140. X#define    ZDOOR        9
  141. X#define    ZSMESS        10
  142. X#define    ZBMESS        11
  143. X
  144. X/*    Dimensions and position of high score table pixmap within window
  145. X*/
  146. X#define SCOREWIDTH    400
  147. X#define SCOREHEIGHT    300
  148. X#define SCOREX        50
  149. X#define SCOREY        180
  150. X
  151. Xextern Display            *display;
  152. Xextern Colormap            colormap;
  153. Xextern Window            rootwindow, gamewindow, infowindow, dialogwindow,
  154. X                        dialogstringwindow, dialogbuttonwindow;
  155. Xextern int                screen, depth;
  156. Xextern unsigned long    blackpixel, whitepixel;
  157. Xextern XFontStruct        *fontinfo, *bigfontinfo;
  158. Xextern Pixmap            drawpixmap, scorepixmap;
  159. Xextern int                dialogwidth, dialogheight;
  160. X
  161. X/*    colors
  162. X*/
  163. X
  164. X#define    NCOLORS    8
  165. X
  166. X#define    CBLACK    0
  167. X#define    CRED    1
  168. X#define    CORANGE    2
  169. X#define    CYELLOW    3
  170. X#define    CBLUE    4
  171. X#define    CGREY    5
  172. X#define    CGREEN    6
  173. X#define    CWHITE    7
  174. X
  175. X/*    two GC's in each colormap entry are needed -- one for the small
  176. X    fixed font, and one for the large Courier font.
  177. X*/
  178. Xstruct colors {
  179. X    char    *name;
  180. X    GC        smallgc;
  181. X    GC        biggc;
  182. X    int        pixelvalue;
  183. X};
  184. X
  185. Xextern struct colors    ctable[8];
  186. X
  187. X/*    maze stuff
  188. X*/
  189. X
  190. X#define    MAXMAZEWIDTH    100
  191. X#define    MAXMAZEHEIGHT    100
  192. X#define    MAXLINES MAXMAZEWIDTH*MAXMAZEHEIGHT*2+MAXMAZEWIDTH+MAXMAZEHEIGHT
  193. X
  194. X#define    WALLUP        0x0001
  195. X#define    WALLRIGHT    0x0002
  196. X#define    WALLDOWN    0x0004
  197. X#define    WALLLEFT    0x0008
  198. X
  199. Xstruct line {
  200. X    int x1, y1, x2, y2;
  201. X};
  202. X
  203. Xextern int            maze[MAXMAZEWIDTH][MAXMAZEHEIGHT];
  204. Xextern struct line    mazelines[MAXLINES];
  205. Xextern int            mazescale, mazewidth, mazeheight, mazelcount;
  206. Xextern char            walldir[4], oppdir[4];
  207. Xextern int            xdir[4], ydir[4];
  208. X
  209. X/*    message stuff
  210. X*/
  211. X
  212. X#define    MAXMESSAGELENGTH    100
  213. X#define    MAXBIGMESSAGELENGTH    30
  214. X#define    MAXLEVELMESSAGES    20
  215. X
  216. X/*    These constants are used to call the dumb_message function when
  217. X    something worth commenting on happens
  218. X*/
  219. X#define    MFUEL        0
  220. X#define    MKILL        1
  221. X#define    MKEY        2
  222. X#define    MCLOSE        3
  223. X#define    MSUICIDE    4
  224. X#define    MEXIT        5
  225. X#define MQUIT        6
  226. X
  227. X/*    Structure used to store the messages triggered in certain areas of a
  228. X    level
  229. X*/
  230. Xstruct levelmessage {
  231. X    char    text[MAXMESSAGELENGTH];
  232. X    char    bigtext[MAXBIGMESSAGELENGTH];
  233. X    int        x1, y1, x2, y2;
  234. X    int        color, bigcolor, time, bigtime;
  235. X    int        active, bigactive, unused;
  236. X};
  237. X
  238. Xextern int                    numlmessage;
  239. Xextern struct levelmessage    lmessage[MAXLEVELMESSAGES];
  240. Xextern char                    messagestring[MAXMESSAGELENGTH],
  241. X                            bigmessagestring[MAXBIGMESSAGELENGTH];
  242. Xextern int                    messagex, messagey, bigmessagex, bigmessagey,
  243. X                            messagecolor, bigmessagecolor,
  244. X                            messagelength, bigmessagelength,
  245. X                            messagewidth, bigmessagewidth,
  246. X                            messagetime, bigmessagetime;
  247. X
  248. X/*    player stuff
  249. X*/
  250. X
  251. X#define    PLAYERWIDTH        20
  252. X#define    PLAYERHEIGHT    20
  253. X#define    PLAYERPARTS        2
  254. X#define    BURNWIDTH        20
  255. X#define    BURNHEIGHT        20
  256. X#define    BURNPARTS        2
  257. X#define    BURNDIRECTIONS    3
  258. X
  259. X#define    FACELEFT    0
  260. X#define    FACEFRONT    7
  261. X#define    FACERIGHT    14
  262. X
  263. X#define PLAYERPHASES    FACERIGHT+1
  264. X
  265. X#define    GOLEFT    -1
  266. X#define    STOP    0
  267. X#define    GORIGHT    1
  268. X
  269. Xextern Pixmap    playerpix[PLAYERPHASES], burnpix[BURNDIRECTIONS];
  270. Xextern int        plx, ply, burn, playerphase, playerdir, playervert,
  271. X                playerfuel, walk, waiting, dead, deadtimer;
  272. X
  273. X/*    pixmaps for exploding player
  274. X*/
  275. X
  276. X#define    EXPLODEWIDTH    30
  277. X#define    EXPLODEHEIGHT    30
  278. X#define    EXPLODEFRAMES    10
  279. X#define    EXPLODETIME        2
  280. X
  281. Xextern Pixmap    explodepix[EXPLODEFRAMES];
  282. Xextern int        exploded, explodetimer;
  283. X
  284. X/*    wall sweepers
  285. X*/
  286. X
  287. X#define    SWEEPERWIDTH    20
  288. X#define    SWEEPERHEIGHT    20
  289. X#define    MAXSWEEPERS        40
  290. X#define    SWEEPERPARTS    3
  291. X#define    SWEEPERPHASES    4
  292. X#define    MAXSWEEPSPEED    10
  293. X
  294. Xextern Pixmap    sweeperpix[SWEEPERPHASES];
  295. Xextern int        numsweep;
  296. Xextern int        sweepx[MAXSWEEPERS], sweepy[MAXSWEEPERS],
  297. X                sweepdir[MAXSWEEPERS], sweepfloor[MAXSWEEPERS],
  298. X                sweepphase[MAXSWEEPERS], sweepspeed[MAXSWEEPERS],
  299. X                sweeprot[MAXSWEEPERS];
  300. X
  301. X/*    fireballs
  302. X*/
  303. X
  304. X#define    FIREWIDTH        20
  305. X#define    FIREHEIGHT        20
  306. X#define    MAXFIREBALLS    40
  307. X#define    FIREPARTS        2
  308. X#define    FIREPHASES        5
  309. X
  310. Xextern Pixmap    firepix[FIREPHASES];
  311. Xextern int        numfire;
  312. Xextern int        firex[MAXFIREBALLS], firey[MAXFIREBALLS],
  313. X                firedx[MAXFIREBALLS], firedy[MAXFIREBALLS],
  314. X                firephase[MAXFIREBALLS];
  315. X
  316. X/*    guards
  317. X*/
  318. X
  319. X#define    GUARDWIDTH        21
  320. X#define    GUARDHEIGHT        21
  321. X#define    MAXGUARDS        40
  322. X#define    GUARDPARTS        2
  323. X#define    GUARDLIGHTS        3
  324. X#define GUARDFLAMEPARTS    2
  325. X#define GUARDDIRECTIONS    4
  326. X#define    GUARDPHASES        8
  327. X#define MAXGUARDSPEED    9
  328. X
  329. Xextern Pixmap    guardpix[GUARDDIRECTIONS][GUARDPHASES];
  330. Xextern int        numguard;
  331. Xextern int        guardx[MAXGUARDS], guardy[MAXGUARDS], guarddir[MAXGUARDS],
  332. X                guardspeed[MAXGUARDS], guardphase[MAXGUARDS],
  333. X                guardtime[MAXGUARDS];
  334. X
  335. X/*    fuel pods
  336. X*/
  337. X
  338. X#define    FUELWIDTH        20
  339. X#define    FUELHEIGHT        20
  340. X#define    MAXFUELPODS        50
  341. X#define    FUELPARTS        4
  342. X#define    FUELINCREMENT    100
  343. X
  344. Xextern Pixmap    fuelpix;
  345. Xextern int        numfuel;
  346. Xextern int        fuelx[MAXFUELPODS], fuely[MAXFUELPODS],
  347. X                fuelalive[MAXFUELPODS], fueltimer[MAXFUELPODS];
  348. X
  349. X/*    key
  350. X*/
  351. X
  352. X#define    KEYWIDTH    10
  353. X#define    KEYHEIGHT    10
  354. X#define    KEYPARTS    1
  355. X
  356. Xextern Pixmap    keypix;
  357. Xextern int        keyx, keyy, keyalive, keytimer;
  358. X
  359. X/*    door
  360. X*/
  361. X
  362. X#define    DOORWIDTH    30
  363. X#define    DOORHEIGHT    30
  364. X#define    DOORPARTS    1
  365. X#define    DOORFRAMES    2
  366. X
  367. Xextern Pixmap    doorpix[DOORFRAMES];
  368. Xextern int        doorx, doory;
  369. Xextern int        indoor;
  370. X
  371. X/*    pixmap of extra man for info window
  372. X*/
  373. X
  374. X#define    EXTRAMANWIDTH    12
  375. X#define    EXTRAMANHEIGHT    20
  376. X
  377. Xextern Pixmap    extramanpix;
  378. X
  379. X/*    dummy coordinates for checking collisions with the maze
  380. X*/
  381. X
  382. Xextern int    nx, ny;
  383. X
  384. X/*    world data
  385. X*/
  386. X
  387. X#define    UPSPEED            -10
  388. X#define    DOWNSPEED        10
  389. X#define THRUST            -2
  390. X#define GRAVITY            1
  391. X#define FUELCAPACITY    1000
  392. X#define BURNCOST        1
  393. X#define PLAYERSPEED        5
  394. X
  395. X/*    game data
  396. X*/
  397. X
  398. X#define    MAXHIGHSCORES    25
  399. X#define    BONUSINCREMENT    10
  400. X#define    BONUSTIME        20
  401. X#define EXTRAMANSCORE    10000
  402. X#define USECDELAY        45000
  403. X
  404. Xextern int    men, score, bonus, bonustimer, initbonus, level;
  405. X            oldscore, oldlevel, extramaninc;
  406. X
  407. X/*    game state
  408. X*/
  409. X
  410. Xextern int    paused, leveldone, gameover, lastscore;
  411. END_OF_FILE
  412. if test 6636 -ne `wc -c <'defs.h'`; then
  413.     echo shar: \"'defs.h'\" unpacked with wrong size!
  414. fi
  415. # end of 'defs.h'
  416. fi
  417. if test -f 'demo.c' -a "${1}" != "-c" ; then 
  418.   echo shar: Will not clobber existing file \"'demo.c'\"
  419. else
  420. echo shar: Extracting \"'demo.c'\" \(4394 characters\)
  421. sed "s/^X//" >'demo.c' <<'END_OF_FILE'
  422. X/*    demo.c : routines that implement the title screen and demonstration.
  423. X*/
  424. X
  425. X#include "copyright.h"
  426. X#include "defs.h"
  427. X
  428. X#define    DEMODELAY    50
  429. X
  430. Xint    demostage, demodelay;
  431. X
  432. X/*    demo is the pseudo-event loop that runs the demo. It is identical to
  433. X    the main loop, except demo_event_filter only checks for input to leave
  434. X    the demo, and demo_player does the actual player action. The level
  435. X    itself is special level 0.
  436. X*/
  437. Xdemo()
  438. X{
  439. X    register unsigned long    timer;
  440. X
  441. X    reset_game();
  442. X    reset_level();
  443. X    level = 0;
  444. X    demostage = 0;
  445. X    if(special_setup() == 0) return;
  446. X    XClearWindow(display, gamewindow);
  447. X    XClearWindow(display, infowindow);
  448. X    draw();
  449. X    refresh_info();
  450. X    while(!leveldone) {
  451. X            begin_timer();
  452. X            while(XPending(display) && !demo_event_filter());
  453. X            demo_player();
  454. X            update();
  455. X            collision_check();
  456. X            message_check();
  457. X            bonus_check();
  458. X            draw();
  459. X            timer = get_timer();
  460. X            if(timer < USECDELAY) usleep(USECDELAY - timer);
  461. X    }
  462. X    XClearWindow(display, gamewindow);
  463. X    XClearWindow(display, infowindow);
  464. X}
  465. X
  466. X/*    title_screen is the animated title screen. There is a "maze" that
  467. X    surrounds the high score list that contain moving enemies. There is
  468. X    also a player suspended in the center going through random motions.
  469. X*/
  470. Xtitle_screen()
  471. X{
  472. X    register unsigned long    timer, btimer;
  473. X    register int            shifttimer, shiftwhich;
  474. X
  475. X    setup_title_maze();
  476. X
  477. X#ifdef    BLIT
  478. X    XFillRectangle(display, drawpixmap, ctable[CBLACK].smallgc, 0, 0,
  479. X                    WINDOWWIDTH, WINDOWHEIGHT);
  480. X#else
  481. X    init_zones();
  482. X#endif
  483. X
  484. X    XClearWindow(display, gamewindow);
  485. X    XClearWindow(display, infowindow);
  486. X    title_refresh();
  487. X    /*    read in the scorefile in case it has changed
  488. X        and draw all the scores for the first time
  489. X    */
  490. X    read_new_scores();
  491. X    shifttimer = 5; shiftwhich = 0;
  492. X    begin_timer();
  493. X    while(gameover) {
  494. X        btimer = get_timer();
  495. X        while(XPending(display)) title_event_filter();
  496. X
  497. X#ifdef    BLIT
  498. X        XCopyArea(display, drawpixmap, gamewindow,
  499. X            ctable[CBLACK].smallgc, 0, 0, WINDOWWIDTH, WINDOWHEIGHT,
  500. X            0, 0);
  501. X#endif
  502. X
  503. X        /*     Only draw 5 scores at a time so there won't be lag
  504. X        */
  505. X        shifttimer--;
  506. X        if(shifttimer == 0) {
  507. X            shifttimer = 5;
  508. X            draw_scores(shiftwhich);
  509. X            shiftwhich++;
  510. X            if(shiftwhich == MAXHIGHSCORES / 5) shiftwhich = 0;
  511. X        }
  512. X        title_draw();
  513. X        timer = get_timer();
  514. X        /*    after 15 seconds, switch to demo
  515. X        */
  516. X        if(timer > 15000000) break;
  517. X        if(timer-btimer < USECDELAY) usleep(USECDELAY-(timer-btimer));
  518. X    }
  519. X    stop_timer();
  520. X    XClearWindow(display, gamewindow);
  521. X    XClearWindow(display, infowindow);
  522. X}
  523. X
  524. X/*    demo_walk is a procedure that makes the demo player walk to a
  525. X    position.
  526. X*/
  527. Xdemo_walk(x)
  528. Xint    x;
  529. X{
  530. X    if(plx > x + 5) playerdir = GOLEFT;
  531. X    else if(plx < x - 5) playerdir = GORIGHT;
  532. X    else {
  533. X        playerdir = STOP;
  534. X        demostage++;
  535. X    }
  536. X}
  537. X
  538. X/*    demo_fly is a procedure that makes the demo player fly to a position.
  539. X*/
  540. Xdemo_fly(x, y)
  541. Xint    x, y;
  542. X{
  543. X    int    maybe = 0;
  544. X
  545. X    if(plx > x + 5) playerdir = GOLEFT;
  546. X    else if(plx < x - 5) playerdir = GORIGHT;
  547. X    else {
  548. X        playerdir = STOP;
  549. X        maybe = 1;
  550. X    }
  551. X    if(ply > y + 5) burn = 1;
  552. X    else if(ply < y - 5) burn = 0;
  553. X    else {
  554. X        burn = 0;
  555. X        if(maybe) demostage++;
  556. X    }
  557. X}
  558. X
  559. X/*    demo_delay makes the demo player wait for a while.
  560. X*/
  561. Xdemo_delay()
  562. X{
  563. X    demodelay--;
  564. X    if(!demodelay) demostage++;
  565. X}
  566. X
  567. X/*    demo_player uses the above macro procedures in a crude switch
  568. X    statement to make the demo player run through the whole routine.
  569. X    A much better implementation would be to have all the data in a static
  570. X    array, but since it's so simple, I'll stick to this for now.
  571. X*/
  572. Xdemo_player()
  573. X{
  574. X    switch(demostage) {
  575. X        case 0:
  576. X            demo_walk(300);
  577. X            demodelay = DEMODELAY;
  578. X            break;
  579. X        case 1:
  580. X            demo_delay();
  581. X            break;
  582. X        case 2:
  583. X            demo_fly(240, 260);
  584. X            break;
  585. X        case 3:
  586. X            demo_fly(400, 350);
  587. X            demodelay = DEMODELAY;
  588. X            break;
  589. X        case 4:
  590. X            demo_delay();
  591. X            break;
  592. X        case 5:
  593. X            demo_walk(660);
  594. X            demodelay = DEMODELAY;
  595. X            break;
  596. X        case 6:
  597. X            demo_delay();
  598. X            break;
  599. X        case 7:
  600. X            demo_walk(1040);
  601. X            demodelay = DEMODELAY;
  602. X            break;
  603. X        case 8:
  604. X            demo_delay();
  605. X            break;
  606. X        case 9:
  607. X            demo_fly(1380, 300);
  608. X            break;
  609. X        case 10:
  610. X            demo_fly(1380, 660);
  611. X            break;
  612. X        case 11:
  613. X            demo_walk(1140);
  614. X            demodelay = DEMODELAY;
  615. X            break;
  616. X        case 12:
  617. X            demo_delay();
  618. X            break;
  619. X        case 13:
  620. X            demo_walk(900);
  621. X            demodelay = DEMODELAY;
  622. X            break;
  623. X        case 14:
  624. X            demo_delay();
  625. X            break;
  626. X        case 15:
  627. X            demo_fly(keyx, keyy);
  628. X            break;
  629. X        case 16:
  630. X            demo_walk(900);
  631. X            break;
  632. X        default:
  633. X            leveldone = 1;
  634. X            break;
  635. X    }
  636. X}
  637. END_OF_FILE
  638. if test 4394 -ne `wc -c <'demo.c'`; then
  639.     echo shar: \"'demo.c'\" unpacked with wrong size!
  640. fi
  641. # end of 'demo.c'
  642. fi
  643. if test -f 'erase.c' -a "${1}" != "-c" ; then 
  644.   echo shar: Will not clobber existing file \"'erase.c'\"
  645. else
  646. echo shar: Extracting \"'erase.c'\" \(7917 characters\)
  647. sed "s/^X//" >'erase.c' <<'END_OF_FILE'
  648. X/*    erase.c : routines used in non-blitting version that erase-and-draw
  649. X    objects and reduce flicker.
  650. X*/
  651. X
  652. X#include "copyright.h"
  653. X#include "defs.h"
  654. X
  655. X/*    Note: the functions and variables in this file are not used in the
  656. X    blitting version.
  657. X*/
  658. X
  659. X#ifndef BLIT
  660. X
  661. X#define MAXOBJECTS 6+MAXLINES+MAXFIREBALLS+MAXSWEEPERS+MAXFUELPODS+MAXGUARDS+MAXHIGHSCORES/5
  662. X
  663. X/*    Structure for eraseable zones that minimize flicker
  664. X*/
  665. Xstruct zone {
  666. X    int    type, num;
  667. X    int    x, y, w, h;
  668. X    int    numtouch;
  669. X    int    touch[MAXOBJECTS];
  670. X    int    erased, drawn;
  671. X};
  672. X
  673. Xint            numzones;
  674. Xstruct zone    zones[MAXOBJECTS];
  675. X
  676. X/*    init_zones initializes the eraseable zones
  677. X*/
  678. Xinit_zones()
  679. X{
  680. X    numzones = 0;
  681. X}
  682. X
  683. X/*    set_zone creates an eraseable zone. x and y are the upper left hand
  684. X    corner, w and h are the width and height of the rectangle, type is the
  685. X    kind of object it is (player, fireball, etc,) and num is the index to
  686. X    the object's information arrays. If type == ZLINE, w and h are used as
  687. X    the second endpoint of a line.
  688. X*/
  689. Xset_zone(x, y, w, h, type, num)
  690. Xint    x, y, w, h, type, num;
  691. X{
  692. X    register int    j;
  693. X
  694. X    zones[numzones].x = x;
  695. X    zones[numzones].y = y;
  696. X    zones[numzones].w = w;
  697. X    zones[numzones].h = h;
  698. X    zones[numzones].type = type;
  699. X    zones[numzones].num = num;
  700. X    zones[numzones].erased = 0;
  701. X    zones[numzones].drawn = 0;
  702. X    zones[numzones].numtouch = 0;
  703. X    for(j=0; j<numzones; j++) {
  704. X        if(zone_intersect(numzones,j)) {
  705. X            zones[j].touch[zones[j].numtouch] = numzones;
  706. X            zones[j].numtouch++;
  707. X            break;
  708. X        }
  709. X    }
  710. X    numzones++;
  711. X}
  712. X
  713. X/*    zone_intersect checks if two zones with indexes i and j touch. There
  714. X    is also a built-in error EDGE, since the player moving around can add
  715. X    some uncertainty to what is covering what.
  716. X*/
  717. Xint    zone_intersect(i, j)
  718. Xint    i, j;
  719. X{
  720. X    if(zones[i].type == ZLINE) {
  721. X        if(zones[j].type == ZLINE) {
  722. X            return((zones[i].w >= zones[j].x - EDGE) && (zones[i].x <=
  723. X                    zones[j].w + EDGE) && (zones[i].h >= zones[j].y -
  724. X                    EDGE) && (zones[i].y <= zones[j].h + EDGE));
  725. X        } else {
  726. X            return((zones[i].w >= zones[j].x - EDGE) && (zones[i].x <=
  727. X                    zones[j].x + zones[j].w + EDGE) && (zones[i].h >=
  728. X                    zones[j].y - EDGE) && (zones[i].y <= zones[j].y +
  729. X                    zones[j].h + EDGE));
  730. X        }
  731. X    } else {
  732. X        if(zones[j].type == ZLINE) {
  733. X            return((zones[j].w >= zones[i].x - EDGE) && (zones[j].x <=
  734. X                    zones[i].x + zones[i].w + EDGE) && (zones[j].h >=
  735. X                    zones[i].y - EDGE) && (zones[j].y <= zones[i].y +
  736. X                    zones[i].h + EDGE));
  737. X        } else {
  738. X            return((zones[i].x > zones[j].x - zones[i].w - EDGE) &&
  739. X                    (zones[i].x < zones[j].x + zones[j].w + EDGE) &&
  740. X                    (zones[i].y > zones[j].y - zones[i].h - EDGE) &&
  741. X                    (zones[i].y < zones[j].y + zones[j].h + EDGE));
  742. X        }
  743. X    }
  744. X}
  745. X
  746. X/*    erase_draw_zones erases all the zones and draws the associated objects
  747. X    in their new positions in such a way as to minimize flicker. The way
  748. X    this works is to erase all zones that touch each other in a group,
  749. X    draw their asscociated objects, then go to the next group. This way
  750. X    the time between erase and draw is minimized for each object while
  751. X    preventing nasty overwriting.
  752. X*/
  753. Xerase_draw_zones()
  754. X{
  755. X    register int    i;
  756. X
  757. X    for(i=0; i<numzones; i++) {
  758. X        erase_recur(i);
  759. X        draw_recur(i);
  760. X    }
  761. X}
  762. X
  763. X/*    erase_recur erases zone i and all the zones that touch it.
  764. X*/
  765. Xerase_recur(i)
  766. Xint    i;
  767. X{
  768. X    register int    j;
  769. X
  770. X    if(zones[i].erased) return;
  771. X    for(j=0; j<zones[i].numtouch; j++) {
  772. X        erase_recur(zones[i].touch[j]);
  773. X    }
  774. X    if(zones[i].type == ZLINE) {
  775. X        XDrawLine(display, gamewindow, ctable[CBLACK].smallgc, zones[i].x,
  776. X                    zones[i].y, zones[i].w, zones[i].h);
  777. X    } else {
  778. X        XFillRectangle(display, gamewindow, ctable[CBLACK].smallgc,
  779. X                        zones[i].x, zones[i].y, zones[i].w, zones[i].h);
  780. X    }
  781. X    zones[i].erased = 1;
  782. X}
  783. X
  784. X/*    draw_recur draws the object associated with zone i and the objects
  785. X    associated with all the zones that touch it.
  786. X*/
  787. Xdraw_recur(i)
  788. Xint    i;
  789. X{
  790. X    register int    j, tmp;
  791. X
  792. X    if(zones[i].drawn) return;
  793. X    for(j=0; j<zones[i].numtouch; j++) {
  794. X        draw_recur(zones[i].touch[j]);
  795. X    }
  796. X    switch(zones[i].type) {
  797. X        case ZLINE:
  798. X            XDrawLine(display, gamewindow, ctable[CWHITE].smallgc,
  799. X                        mazelines[zones[i].num].x1 - plx + WINDOWWIDTH / 2,
  800. X                        mazelines[zones[i].num].y1 - ply + WINDOWHEIGHT / 2,
  801. X                        mazelines[zones[i].num].x2 - plx + WINDOWWIDTH / 2,
  802. X                        mazelines[zones[i].num].y2 - ply + WINDOWHEIGHT / 2);
  803. X            break;
  804. X        case ZPLAYER:
  805. X            if(!dead && (exploded == -1)) {
  806. X                XCopyArea(display, playerpix[playerphase], gamewindow,
  807. X                            ctable[CWHITE].smallgc, 0, 0, PLAYERWIDTH,
  808. X                            PLAYERHEIGHT, WINDOWWIDTH / 2 - PLAYERWIDTH / 2,
  809. X                            WINDOWHEIGHT / 2 - PLAYERHEIGHT / 2);
  810. X            }
  811. X            break;
  812. X        case ZBURN:
  813. X            if(!dead && (exploded == -1) && burn) {
  814. X                XCopyArea(display, burnpix[playerphase / FACEFRONT],
  815. X                            gamewindow, ctable[CWHITE].smallgc, 0, 0,
  816. X                            PLAYERWIDTH, PLAYERHEIGHT, WINDOWWIDTH / 2 -
  817. X                            PLAYERWIDTH / 2, WINDOWHEIGHT / 2 - PLAYERHEIGHT
  818. X                            / 2);
  819. X            }
  820. X            break;
  821. X        case ZEXPLODE:
  822. X            if(!dead && (exploded > -1)) {
  823. X                XCopyArea(display, explodepix[exploded], gamewindow,
  824. X                            ctable[CWHITE].smallgc, 0, 0, EXPLODEWIDTH,
  825. X                            EXPLODEHEIGHT, WINDOWWIDTH / 2 - EXPLODEWIDTH / 2,
  826. X                            WINDOWHEIGHT / 2 - EXPLODEHEIGHT / 2);
  827. X            }
  828. X            break;
  829. X        case ZFIRE:
  830. X            XCopyArea(display, firepix[firephase[zones[i].num]],
  831. X                        gamewindow, ctable[CWHITE].smallgc, 0, 0,
  832. X                        FIREWIDTH, FIREHEIGHT, transx(firex[zones[i].num],
  833. X                        FIREWIDTH), transy(firey[zones[i].num],
  834. X                        FIREHEIGHT));
  835. X            break;
  836. X        case ZGUARD:
  837. X            XCopyArea(display,
  838. X                guardpix[guarddir[zones[i].num]][guardphase[zones[i].num]],
  839. X                        gamewindow, ctable[CWHITE].smallgc, 0, 0,
  840. X                        GUARDWIDTH, GUARDHEIGHT, transx(guardx[zones[i].num],
  841. X                        GUARDWIDTH), transy(guardy[zones[i].num],
  842. X                        GUARDHEIGHT));
  843. X            break;
  844. X        case ZSWEEP:
  845. X            XCopyArea(display, sweeperpix[sweepphase[zones[i].num]],
  846. X                        gamewindow, ctable[CWHITE].smallgc, 0, 0,
  847. X                        SWEEPERWIDTH, SWEEPERHEIGHT,
  848. X                        transx(sweepx[zones[i].num], SWEEPERWIDTH),
  849. X                        transy(sweepy[zones[i].num], SWEEPERHEIGHT));
  850. X            break;
  851. X        case ZFUEL:
  852. X            if(fuelalive[zones[i].num]) {
  853. X                XCopyArea(display, fuelpix, gamewindow,
  854. X                            ctable[CWHITE].smallgc, 0, 0, FUELWIDTH,
  855. X                            FUELHEIGHT, transx(fuelx[zones[i].num],
  856. X                            FUELWIDTH), transy(fuely[zones[i].num],
  857. X                            FUELHEIGHT));
  858. X            } else if(fueltimer[zones[i].num]) {
  859. X                tmp = XTextWidth(fontinfo, "100", 3) / 2;
  860. X                XDrawString(display, gamewindow, ctable[CGREEN].smallgc,
  861. X                            fuelx[zones[i].num] - plx + WINDOWWIDTH / 2 -
  862. X                            tmp, fuely[zones[i].num] - ply +
  863. X                            WINDOWHEIGHT / 2, "100", 3);
  864. X            }
  865. X            break;
  866. X        case ZKEY:
  867. X            if(keyalive) {
  868. X                XCopyArea(display, keypix, gamewindow,
  869. X                            ctable[CWHITE].smallgc, 0, 0, KEYWIDTH,
  870. X                            KEYHEIGHT, transx(keyx, KEYWIDTH),
  871. X                            transy(keyy, KEYHEIGHT));
  872. X            } else if(keytimer) {
  873. X                tmp = XTextWidth(fontinfo, "500", 3) / 2;
  874. X                XDrawString(display, gamewindow, ctable[CGREEN].smallgc,
  875. X                            keyx - plx + WINDOWWIDTH / 2 - tmp, keyy -
  876. X                            ply + WINDOWHEIGHT / 2, "500", 3);
  877. X            }
  878. X            break;
  879. X        case ZDOOR:
  880. X            tmp = indoor;
  881. X            if(indoor && (exploded > -1))  tmp = 0;
  882. X            XCopyArea(display, doorpix[tmp], gamewindow,
  883. X                        ctable[CWHITE].smallgc, 0, 0, DOORWIDTH,
  884. X                        DOORHEIGHT, transx(doorx, DOORWIDTH),
  885. X                        transy(doory, DOORHEIGHT) - (DOORHEIGHT -
  886. X                        PLAYERHEIGHT) / 2);
  887. X            break;
  888. X        case ZSMESS:
  889. X            if(messagetime != 0) {
  890. X                if(messagecolor == CBLACK) tmp = random() % (NCOLORS-1) + 1;
  891. X                else tmp = messagecolor;
  892. X                XDrawString(display, gamewindow, ctable[tmp].smallgc,
  893. X                            messagex, messagey, messagestring, messagelength);
  894. X            }
  895. X            break;
  896. X        case ZBMESS:
  897. X            if(bigmessagetime != 0) {
  898. X                if(bigmessagecolor == CBLACK) tmp = random() % (NCOLORS-1) + 1;
  899. X                else tmp = bigmessagecolor;
  900. X                XDrawString(display, gamewindow, ctable[tmp].biggc,
  901. X                            bigmessagex, bigmessagey, bigmessagestring, 
  902. X                            bigmessagelength);
  903. X            }
  904. X            break;
  905. X    }
  906. X    zones[i].drawn = 1;
  907. X}
  908. X
  909. X/*    refresh draws all the objects
  910. X*/
  911. Xrefresh()
  912. X{
  913. X    register int    i;
  914. X
  915. X    for(i=0; i<numzones; i++) {
  916. X        draw_recur(i);
  917. X    }
  918. X    for(i=0; i<numzones; i++) {
  919. X        zones[i].drawn = 0;
  920. X    }
  921. X}
  922. X
  923. X#endif
  924. END_OF_FILE
  925. if test 7917 -ne `wc -c <'erase.c'`; then
  926.     echo shar: \"'erase.c'\" unpacked with wrong size!
  927. fi
  928. # end of 'erase.c'
  929. fi
  930. if test -f 'initx.c' -a "${1}" != "-c" ; then 
  931.   echo shar: Will not clobber existing file \"'initx.c'\"
  932. else
  933. echo shar: Extracting \"'initx.c'\" \(4961 characters\)
  934. sed "s/^X//" >'initx.c' <<'END_OF_FILE'
  935. X/*    initx.c : routines that set up the X resources and colors.
  936. X*/
  937. X
  938. X#include "copyright.h"
  939. X#include "defs.h"
  940. X
  941. XDisplay            *display;
  942. XColormap        colormap;
  943. XWindow            rootwindow;
  944. Xint                screen, depth;
  945. Xunsigned long    blackpixel, whitepixel;
  946. XXFontStruct        *fontinfo, *bigfontinfo;
  947. X
  948. X/*    initialize the colortable with the names of the colors (from rgb.txt)
  949. X*/
  950. Xstruct colors    ctable[] = {
  951. X    { "black"        },
  952. X    { "red"            },
  953. X    { "orange"        },
  954. X    { "yellow"        },
  955. X    { "RoyalBlue2"    },
  956. X    { "grey50"        },
  957. X    { "green"        },
  958. X    { "white"        }
  959. X};
  960. X
  961. X/*    Depending on your system, the fontnames listed here may not be
  962. X    complete enough to pick the right font. The system I developed on
  963. X    has 475 fonts, so these should be specific enough. But just in
  964. X    case, here are the full fontnames:
  965. X
  966. X    small font:
  967. X    -misc-fixed-medium-r-normal--10-70-100-100-c-60-iso8859-1
  968. X
  969. X    big font:
  970. X    -adobe-courier-bold-r-normal--25-180-100-100-m-150-iso8859-1
  971. X
  972. X    It also might be that you won't have these fonts. If not, pick two
  973. X    fonts that look good. The program adjusts things on the screen for
  974. X    whatever fonts the program uses, so almost anything should do.
  975. X    Just pick a pretty small font for the small font, and a reasonably
  976. X    large font for the big font. Use xfontsel to make this easier
  977. X    since it makes it really easy to pick fonts, and you can paste the
  978. X    resulting fontname right into the code.
  979. X*/
  980. X
  981. Xstatic char    *fontname = "-*-fixed-medium-r-normal--*-70-*-*-c-*-*-*";
  982. Xstatic char    *bigfontname = "-*-courier-bold-r-normal--*-180-*-*-m-150-*-*";
  983. X
  984. X/*    init_X opens the display and sets up all the color stuff
  985. X*/
  986. Xinit_X()
  987. X{
  988. X    display = XOpenDisplay(NULL);
  989. X    if (display == NULL) {
  990. X       fprintf(stderr, "Jetpack : Cannot connect to X Server %s\n",
  991. X               XDisplayName(NULL));
  992. X       exit(1);
  993. X    }
  994. X    rootwindow = DefaultRootWindow(display);
  995. X    screen = DefaultScreen(display);
  996. X    colormap = DefaultColormap(display, screen);
  997. X    depth = DefaultDepth(display, screen);
  998. X       blackpixel = BlackPixel(display, screen);
  999. X       whitepixel = WhitePixel(display, screen);
  1000. X    set_up_colors();
  1001. X    set_up_contexts();
  1002. X}
  1003. X
  1004. X/*    set_up_contexts creates the graphics smallgcs used in the game, and
  1005. X    stores them in the ctable array. The fonts are created here too.
  1006. X*/
  1007. Xset_up_contexts()
  1008. X{
  1009. X    int            i;
  1010. X    XGCValues    values;
  1011. X    Font        small, big;
  1012. X
  1013. X    fontinfo = XLoadQueryFont(display, fontname);
  1014. X    if(fontinfo == NULL) {
  1015. X        fprintf(stderr, "Jetpack : Couldn't load %s font.\n",fontname);
  1016. X        exit(1);
  1017. X    }
  1018. X    bigfontinfo = XLoadQueryFont(display, bigfontname);
  1019. X    if(bigfontinfo == NULL) {
  1020. X        fprintf(stderr, "Jetpack : Couldn't load %s font.\n",bigfontname);
  1021. X        exit(1);
  1022. X    }
  1023. X    big = bigfontinfo->fid;
  1024. X    small = fontinfo->fid;
  1025. X    values.font = small;
  1026. X    values.function = GXcopy;
  1027. X    ctable[CBLACK].smallgc = XCreateGC(display, rootwindow,
  1028. X                                        GCFunction|GCFont, &values);
  1029. X    values.font = big;
  1030. X    ctable[CBLACK].biggc = XCreateGC(display, rootwindow,
  1031. X                                        GCFunction|GCFont, &values);
  1032. X    values.function = GXor;
  1033. X    for(i=1; i<NCOLORS; i++) {
  1034. X        values.font = small;
  1035. X        ctable[i].smallgc = XCreateGC(display, rootwindow,
  1036. X                                        GCFunction|GCFont, &values);
  1037. X        values.font = big;
  1038. X        ctable[i].biggc = XCreateGC(display, rootwindow,
  1039. X                                    GCFunction|GCFont, &values);
  1040. X    }
  1041. X    for(i=0; i<NCOLORS; i++) {
  1042. X        XSetForeground(display, ctable[i].smallgc,
  1043. X                        ctable[i].pixelvalue);
  1044. X        XSetBackground(display, ctable[i].smallgc,
  1045. X                        ctable[CBLACK].pixelvalue);
  1046. X        XSetForeground(display, ctable[i].biggc,
  1047. X                        ctable[i].pixelvalue);
  1048. X        XSetBackground(display, ctable[i].biggc,
  1049. X                        ctable[CBLACK].pixelvalue);
  1050. X    }
  1051. X}
  1052. X
  1053. X/*    set_up_colors creates the colors and stores them in the graphics
  1054. X    smallgcs. If the system is mono, all colors are white except CBLACK.
  1055. X    This isn't very elegant, but I use the colors for so many different
  1056. X    items that it would be impossible to set some of them to black and not
  1057. X    lose some important images. It's still playable.
  1058. X*/
  1059. Xset_up_colors()
  1060. X{
  1061. X    int                i;
  1062. X    XColor            tmpcolor;
  1063. X    unsigned long    pixel, planes[3];
  1064. X
  1065. X    if(DisplayCells(display, screen) <= 2) {
  1066. X        for(i=0; i<NCOLORS; i++) {
  1067. X            if(i == CBLACK) ctable[i].pixelvalue = blackpixel;
  1068. X            else ctable[i].pixelvalue = whitepixel;
  1069. X        }
  1070. X    } else {
  1071. X        XAllocColorCells(display, colormap, False, planes, 3, &pixel, 1);
  1072. X        for(i=0; i<NCOLORS; i++) {
  1073. X            XParseColor(display, colormap, ctable[i].name, &tmpcolor);
  1074. X            switch(i) {
  1075. X                case CBLACK:
  1076. X                    tmpcolor.pixel = pixel;
  1077. X                    break;
  1078. X                case CRED:
  1079. X                    tmpcolor.pixel = pixel | planes[0];
  1080. X                    break;
  1081. X                case CORANGE:
  1082. X                    tmpcolor.pixel = pixel | planes[1];
  1083. X                    break;
  1084. X                case CYELLOW:
  1085. X                    tmpcolor.pixel = pixel | planes[1] | planes[0];
  1086. X                    break;
  1087. X                case CBLUE:
  1088. X                    tmpcolor.pixel = pixel | planes[2];
  1089. X                    break;
  1090. X                case CGREY:
  1091. X                    tmpcolor.pixel = pixel | planes[2] | planes[0];
  1092. X                    break;
  1093. X                case CGREEN:
  1094. X                    tmpcolor.pixel = pixel | planes[2] | planes[1];
  1095. X                    break;
  1096. X                case CWHITE:
  1097. X                    tmpcolor.pixel = pixel | planes[2] | planes[1] | planes[0];
  1098. X                    break;
  1099. X            }
  1100. X            XStoreColor(display, colormap, &tmpcolor);
  1101. X            ctable[i].pixelvalue = tmpcolor.pixel;
  1102. X        }
  1103. X    }
  1104. X}
  1105. END_OF_FILE
  1106. if test 4961 -ne `wc -c <'initx.c'`; then
  1107.     echo shar: \"'initx.c'\" unpacked with wrong size!
  1108. fi
  1109. # end of 'initx.c'
  1110. fi
  1111. if test -f 'maze.c' -a "${1}" != "-c" ; then 
  1112.   echo shar: Will not clobber existing file \"'maze.c'\"
  1113. else
  1114. echo shar: Extracting \"'maze.c'\" \(4831 characters\)
  1115. sed "s/^X//" >'maze.c' <<'END_OF_FILE'
  1116. X/*    maze.c : routines that generate the mazes
  1117. X*/
  1118. X
  1119. X#include "copyright.h"
  1120. X#include "defs.h"
  1121. X
  1122. X/*    These arrays are used to implement direction.
  1123. X*/
  1124. Xchar    walldir[4] = { WALLUP, WALLRIGHT, WALLDOWN, WALLLEFT };
  1125. Xchar    oppdir[4] = { WALLDOWN, WALLLEFT, WALLUP, WALLRIGHT };
  1126. Xint        xdir[4] = { 0, 1, 0, -1 };
  1127. Xint        ydir[4] = { -1, 0, 1, 0 };
  1128. X
  1129. Xint            maze[MAXMAZEWIDTH][MAXMAZEHEIGHT];
  1130. Xstruct line    mazelines[MAXLINES];
  1131. Xint            mazescale, mazelcount, mazewidth, mazeheight;
  1132. X
  1133. X/*    generate maze uses a digging algorithm to generate the maze.
  1134. X*/
  1135. Xgenerate_maze(width, height, ratio, twistratio)
  1136. Xint    width, height;
  1137. Xfloat ratio, twistratio;
  1138. X{
  1139. X    register int    x, y, d, cells, lines, twist, dug;
  1140. X    char            celldone[MAXMAZEWIDTH][MAXMAZEHEIGHT];
  1141. X
  1142. X    mazelcount = 0;
  1143. X    if(width > MAXMAZEWIDTH - 1) width = MAXMAZEWIDTH - 1;
  1144. X    if(height > MAXMAZEHEIGHT - 1) height = MAXMAZEHEIGHT - 1;
  1145. X    mazewidth = width;
  1146. X    mazeheight = height;
  1147. X    lines = (int) ((mazewidth-1)*(mazeheight-1) * ratio);
  1148. X    twist = (int) (twistratio * width * height);
  1149. X
  1150. X    /*    Make the maze full of walls.
  1151. X    */
  1152. X    for(x=0; x < MAXMAZEWIDTH; x++)
  1153. X        for(y=0; y < MAXMAZEHEIGHT; y++) {
  1154. X            maze[x][y] = (WALLUP | WALLDOWN | WALLLEFT | WALLRIGHT);
  1155. X            celldone[x][y] = 0;
  1156. X        }
  1157. X
  1158. X    /*    Alter the edges of the maze so the algorithm uses them as
  1159. X        boundaries.
  1160. X    */
  1161. X    for(x=0; x < width + 1; x++) {
  1162. X        celldone[x][0] = 1;
  1163. X        celldone[x][height+1] = 1;
  1164. X        maze[x][0] = 0;
  1165. X        maze[x][height+1] = WALLUP;
  1166. X    }
  1167. X    for(y=0; y < height + 1; y++) {
  1168. X        celldone[0][y] = 1;
  1169. X        celldone[width+1][y] = 1;
  1170. X        maze[0][y] = 0;
  1171. X        maze[width+1][y] = WALLLEFT;
  1172. X    }
  1173. X    maze[width+1][height+1] = 0;
  1174. X
  1175. X    /*    Pick a random cell to start and clear it.
  1176. X    */
  1177. X    x = random() % width + 1;
  1178. X    y = random() % height + 1;
  1179. X    cells = width * height - 1;
  1180. X    celldone[x][y] = 1;
  1181. X    dug = 0;
  1182. X    while(cells > 0) {
  1183. X
  1184. X        /*    If we aren't in a dug cell or the cell we are in is completely
  1185. X            surrounded by dug cells or we've dug the maximum length of a
  1186. X            passage, go to a new cell.
  1187. X        */
  1188. X        while((!celldone[x][y]) ||
  1189. X            (celldone[x][y-1] && celldone[x-1][y] && celldone[x][y+1] &&
  1190. X            celldone[x+1][y]) || (dug > twist)) {
  1191. X            x = random() % width + 1;
  1192. X            y = random() % height + 1;
  1193. X            dug = 0;
  1194. X        }
  1195. X
  1196. X        /*    Pick a direction that has a wall
  1197. X        */
  1198. X        do {
  1199. X            d = random() % 4;
  1200. X        } while(celldone[x+xdir[d]][y+ydir[d]]);
  1201. X
  1202. X        /* Dig!
  1203. X        */
  1204. X        cells--;
  1205. X        maze[x][y] &= ~(walldir[d]);
  1206. X        x += xdir[d];
  1207. X        y += ydir[d];
  1208. X        celldone[x][y] = 1;
  1209. X        maze[x][y] &= ~(oppdir[d]);
  1210. X        dug++;
  1211. X    }
  1212. X
  1213. X    /*    Remove random lines according to the ratio passed.
  1214. X    */
  1215. X    while(lines > 0) {
  1216. X        do {
  1217. X            do {
  1218. X                x = random() % width + 1;
  1219. X                y = random() % height + 1;
  1220. X            } while(!maze[x][y]);
  1221. X            do {
  1222. X                d = random() % 4;
  1223. X            } while(!(maze[x][y] & walldir[d]));
  1224. X        } while((x+xdir[d] <= 0) || (x+xdir[d] >= mazewidth + 1) ||
  1225. X                (y+ydir[d] <= 0) || (y+ydir[d] >= mazeheight + 1));
  1226. X        maze[x][y] &= ~(walldir[d]);
  1227. X        maze[x+xdir[d]][y+ydir[d]] &= ~(oppdir[d]);
  1228. X        lines--;
  1229. X    }
  1230. X
  1231. X    /*    Create the lines used for drawing the maze.
  1232. X    */
  1233. X    convert_maze(width, height);
  1234. X}
  1235. X
  1236. X/*    add_line adds a world-coordinates line to the maze drawing
  1237. X*/
  1238. Xadd_line( x1, y1, x2, y2)
  1239. Xint    x1, y1, x2, y2;
  1240. X{
  1241. X    mazelines[mazelcount].x1 = x1;
  1242. X    mazelines[mazelcount].y1 = y1;
  1243. X    mazelines[mazelcount].x2 = x2;
  1244. X    mazelines[mazelcount].y2 = y2;
  1245. X    mazelcount++;
  1246. X}
  1247. X
  1248. X/*    convert_maze creates a world drawing of the maze from its array
  1249. X    structure.
  1250. X*/
  1251. Xconvert_maze(width, height)
  1252. Xint    width, height;
  1253. X{
  1254. X    int x, y;
  1255. X
  1256. X    for(x=1; x<width+2; x++)
  1257. X        for(y=1; y <height+2; y++) {
  1258. X            if(maze[x][y] & WALLUP) add_line(x*mazescale, y*mazescale,
  1259. X                                                (x+1)*mazescale, y*mazescale);
  1260. X            if(maze[x][y] & WALLLEFT) add_line(x*mazescale, y*mazescale,
  1261. X                                                x*mazescale, (y+1)*mazescale);
  1262. X        }
  1263. X}
  1264. X
  1265. X/*  setup_title_maze creates the trivial maze that the title screen uses,
  1266. X    and creates the monsters that cavort in it.
  1267. X*/
  1268. Xsetup_title_maze()
  1269. X
  1270. X{
  1271. X    mazewidth = 4;
  1272. X    mazeheight = 3;
  1273. X    mazescale = 100;
  1274. X    mazelcount = 0;
  1275. X    maze[0][0] = 0; maze[1][0] = 4; maze[2][0] = 4; maze[3][0] = 4;
  1276. X    maze[4][0] = 4; maze[5][0] = 0; maze[0][1] = 2; maze[1][1] = 9;
  1277. X    maze[2][1] = 1; maze[3][1] = 1; maze[4][1] = 3; maze[5][1] = 8;
  1278. X    maze[0][2] = 2; maze[1][2] = 8; maze[2][2] = 0; maze[3][2] = 0;
  1279. X    maze[4][2] = 2; maze[5][2] = 8; maze[0][3] = 2; maze[1][3] = 12;
  1280. X    maze[2][3] = 4; maze[3][3] = 4; maze[4][3] = 6; maze[5][3] = 8;
  1281. X    maze[0][4] = 0; maze[1][4] = 1; maze[2][4] = 1; maze[3][4] = 1;
  1282. X    maze[4][4] = 1; maze[5][4] = 0;
  1283. X    convert_maze(4, 3);
  1284. X    plx = 300; ply = 170;
  1285. X    playerphase = FACEFRONT; playerdir = STOP; burn = 0;
  1286. X    random_fireballs(random() % 3 + 2, 3, 7);
  1287. X    random_guards(random() % 3 + 1, 3, 7);
  1288. X    numsweep = 0;
  1289. X    place_sweeper(random() % 4 + 1, 0, 2, 1, random() % 5 + 1);
  1290. X    place_sweeper(random() % 4 + 1, 4, 0, 1, random() % 5 + 1);
  1291. X    place_sweeper(0,random() % 3 + 1, 1, 1, random() % 5 + 1);
  1292. X    place_sweeper(5,random() % 3 + 1, 3, 1, random() % 5 + 1);
  1293. X}
  1294. END_OF_FILE
  1295. if test 4831 -ne `wc -c <'maze.c'`; then
  1296.     echo shar: \"'maze.c'\" unpacked with wrong size!
  1297. fi
  1298. # end of 'maze.c'
  1299. fi
  1300. if test -f 'normal.c' -a "${1}" != "-c" ; then 
  1301.   echo shar: Will not clobber existing file \"'normal.c'\"
  1302. else
  1303. echo shar: Extracting \"'normal.c'\" \(4732 characters\)
  1304. sed "s/^X//" >'normal.c' <<'END_OF_FILE'
  1305. X/*    normal.c : routine that sets up the levels that aren't predefined
  1306. X*/
  1307. X
  1308. X#include "copyright.h"
  1309. X#include "defs.h"
  1310. X
  1311. X/* normal_level is a very ugly switch statement that sets up the various
  1312. X    types of "normal" levels
  1313. X*/
  1314. Xnormal_level()
  1315. X{
  1316. X    register int    mx, my, f, p, s, n, md, mt, msc, fmin, fmax, smin, smax,
  1317. X                    g, gmin, gmax, kind, obj;
  1318. X
  1319. X    /*    there are 5 kinds of "normal" levels: Open levels, Big levels,
  1320. X        Twisty levels, and Death levels
  1321. X    */
  1322. X    kind = level % 8;
  1323. X    switch(kind) {
  1324. X        /*    Twisty level: medium large maze, all walls, normal fuel and
  1325. X            enemies, many intersections.
  1326. X        */
  1327. X        case 0:
  1328. X            message("Twisty Level", CGREEN, 75);
  1329. X            msc = random() % 50 + 100;
  1330. X            mx = random() % 15 + 5;
  1331. X            my = random() % 15 + 5;
  1332. X            md = 0;
  1333. X            mt = 0;
  1334. X            obj = (mx * my * msc) / 500;
  1335. X            if(obj > 30) obj = 30;
  1336. X            do {
  1337. X                f = random() % 30;
  1338. X                s = random() % 30;
  1339. X                g = random() % 30;
  1340. X            } while((f + s + g > obj) || (f + s + g < obj / 2));
  1341. X            p = random() % (obj / 4) + obj / 4;
  1342. X            smin = level / 3 + 1;
  1343. X            smax = level / 3 + 3;
  1344. X            if(smin > 5) smin = 5;
  1345. X            fmin = level / 3 - 1;
  1346. X            fmax = level / 3 + 3;
  1347. X            if(fmin > 5) fmin = 5;
  1348. X            gmin = level / 3 + 1;
  1349. X            gmax = level / 3 + 3;
  1350. X            if(gmin > 5) gmin = 5;
  1351. X            make_random_level(mx, my, msc, md, mt, f, fmin, fmax, s, smin, smax,
  1352. X                                g, gmin, gmax, p);
  1353. X            break;
  1354. X
  1355. X        /*    Open level: medium size maze, very few walls, normal level of
  1356. X            fuel and enemies
  1357. X        */
  1358. X        case 2:
  1359. X            message("Open Level", CORANGE, 75);
  1360. X            msc = random() % 75 + 75;
  1361. X            mx = random() % 20 + 5;
  1362. X            my = random() % 20 + 5;
  1363. X            md = random() % 30 + 71;
  1364. X            mt = 100;
  1365. X            obj = (mx * my * msc) / 500;
  1366. X            if(obj > 30) obj = 30;
  1367. X            do {
  1368. X                f = random() % 30;
  1369. X                s = random() % 30;
  1370. X                g = random() % 30;
  1371. X            } while((f + s + g > obj) || (f + s + g < obj / 2));
  1372. X            p = random() % (obj / 4) + obj / 4;
  1373. X            smin = level / 3 + 1;
  1374. X            smax = level / 3 + 3;
  1375. X            if(smin > 5) smin = 5;
  1376. X            fmin = level / 3 - 1;
  1377. X            fmax = level / 3 + 3;
  1378. X            if(fmin > 5) fmin = 5;
  1379. X            gmin = level / 3 + 1;
  1380. X            gmax = level / 3 + 3;
  1381. X            if(gmin > 5) gmin = 5;
  1382. X            make_random_level(mx, my, msc, md, mt, f, fmin, fmax, s, smin, smax,
  1383. X                                g, gmin, gmax, p);
  1384. X            break;
  1385. X        /*    Big level: large maze, very few walls missing if any, normal
  1386. X            level of fuel and enemies
  1387. X        */
  1388. X        case 6:
  1389. X            message("Big Level", CYELLOW, 75);
  1390. X            msc = random() % 25 + 125;
  1391. X            mx = random() % 10 + 15;
  1392. X            my = random() % 10 + 15;
  1393. X            if(random() % 3 == 0) md = random() % 5;
  1394. X            else md = 0;
  1395. X            mt = random() % 101;
  1396. X            obj = (mx * my * msc) / 500;
  1397. X            p = obj / 2;
  1398. X            if(obj > 30) obj = 30;
  1399. X            do {
  1400. X                f = random() % 30;
  1401. X                s = random() % 30;
  1402. X                g = random() % 30;
  1403. X            } while((f + s + g > obj) || (f + s + g < obj / 2));
  1404. X            smin = level / 3 + 1;
  1405. X            smax = level / 3 + 3;
  1406. X            if(smin > 5) smin = 5;
  1407. X            fmin = level / 3 - 1;
  1408. X            fmax = level / 3 + 3;
  1409. X            if(fmin > 5) fmin = 5;
  1410. X            gmin = level / 3 + 1;
  1411. X            gmax = level / 3 + 3;
  1412. X            if(gmin > 5) gmin = 5;
  1413. X            make_random_level(mx, my, msc, md, mt, f, fmin, fmax, s, smin, smax,
  1414. X                                g, gmin, gmax, p);
  1415. X            break;
  1416. X        /*    Death level: small maze, few walls missing, little fuel, two
  1417. X            to three times normal level of enemies
  1418. X        */
  1419. X        case 4:
  1420. X            message("Death Level", CRED, 75);
  1421. X            msc = random() % 20 + 100;
  1422. X            mx = random() % 5 + 5;
  1423. X            my = random() % 5 + 5;
  1424. X            md = random() % 10;
  1425. X            mt = random() % 101;
  1426. X            obj = (mx * my * msc) / 500;
  1427. X            do {
  1428. X                f = random() % 30;
  1429. X                s = random() % 30;
  1430. X                g = random() % 30;
  1431. X            } while((f + s + g > obj * 3) || (f + s + g < obj * 2));
  1432. X            p = random() % (obj / 4) + obj / 3;
  1433. X            smin = level / 3 + 1;
  1434. X            smax = level / 3 + 3;
  1435. X            if(smin > 5) smin = 5;
  1436. X            fmin = level / 3 - 1;
  1437. X            fmax = level / 3 + 3;
  1438. X            if(fmin > 5) fmin = 5;
  1439. X            gmin = level / 3 + 1;
  1440. X            gmax = level / 3 + 3;
  1441. X            if(gmin > 5) gmin = 5;
  1442. X            make_random_level(mx, my, msc, md, mt, f, fmin, fmax, s, smin, smax,
  1443. X                                g, gmin, gmax, p);
  1444. X            break;
  1445. X        /*    Ordinary level: normal level of fuel and enemies, maze
  1446. X            varies.
  1447. X        */
  1448. X        default:
  1449. X            msc = random() % 75 + 75;
  1450. X            mx = random() % 15 + 5;
  1451. X            my = random() % 15 + 5;
  1452. X            n = random() % 10;
  1453. X            if(n == 0) {
  1454. X                md = random() % 90 + 11;
  1455. X            } else if(n < 4) {
  1456. X                md = random() % 10 + 1;
  1457. X            } else md = 0;
  1458. X            mt = random() % 101;
  1459. X            obj = (mx * my * msc) / 500;
  1460. X            if(obj > 30) obj = 30;
  1461. X            do {
  1462. X                f = random() % 30;
  1463. X                s = random() % 30;
  1464. X                g = random() % 30;
  1465. X            } while((f + s + g > obj) || (f + s + g < obj / 2));
  1466. X            p = random() % (obj / 4) + obj / 3;
  1467. X            smin = level / 3 + 1;
  1468. X            smax = level / 3 + 3;
  1469. X            if(smin > 5) smin = 5;
  1470. X            fmin = level / 3 - 1;
  1471. X            fmax = level / 3 + 3;
  1472. X            if(fmin > 5) fmin = 5;
  1473. X            gmin = level / 3 + 1;
  1474. X            gmax = level / 3 + 3;
  1475. X            if(gmin > 5) gmin = 5;
  1476. X            make_random_level(mx, my, msc, md, mt, f, fmin, fmax, s, smin, smax,
  1477. X                                g, gmin, gmax, p);
  1478. X            break;
  1479. X    }
  1480. X}
  1481. END_OF_FILE
  1482. if test 4732 -ne `wc -c <'normal.c'`; then
  1483.     echo shar: \"'normal.c'\" unpacked with wrong size!
  1484. fi
  1485. # end of 'normal.c'
  1486. fi
  1487. if test -f 'setup.c' -a "${1}" != "-c" ; then 
  1488.   echo shar: Will not clobber existing file \"'setup.c'\"
  1489. else
  1490. echo shar: Extracting \"'setup.c'\" \(8638 characters\)
  1491. sed "s/^X//" >'setup.c' <<'END_OF_FILE'
  1492. X/*    setup.c : routines used to setup level stuff.
  1493. X*/
  1494. X
  1495. X#include "copyright.h"
  1496. X#include "defs.h"
  1497. X
  1498. X/*    make_random_level takes its huge list of arguments and creates a
  1499. X    level.
  1500. X*/
  1501. Xmake_random_level(mx, my, msc, md, mt, f, fmin, fmax, s, smin, smax, g, gmin,
  1502. X                    gmax, p)
  1503. Xint mx, my, msc, md, mt, f, fmin, fmax, s, smin, smax, g, gmin, gmax, p;
  1504. X{
  1505. X    float    r, t;
  1506. X
  1507. X    mazescale = msc;
  1508. X    r = ((float) md) / 100.0;
  1509. X    t = ((float) mt) / 100.0;
  1510. X    generate_maze(mx, my, r, t);
  1511. X    random_player();
  1512. X    random_fireballs(f, fmin, fmax);
  1513. X    random_fuel(p);
  1514. X    random_sweepers(s, smin, smax);
  1515. X    random_guards(g, gmin, gmax);
  1516. X    random_key();
  1517. X    if(r > 0.75) r = 0.75;
  1518. X    bonus = (((int) (mazewidth * mazeheight * mazescale * (1 - r)) -
  1519. X                p * 100 + s * 50 + g * 50 + f * 100) / 100) * 10;
  1520. X    if(bonus < 500) bonus = 500;
  1521. X    initbonus = bonus;
  1522. X}
  1523. X
  1524. X/*    reset_level just gives values to certain global variables that need to
  1525. X    be initialized for each level.
  1526. X*/
  1527. Xreset_level()
  1528. X{
  1529. X    leveldone = 0;
  1530. X    waiting = 0;
  1531. X    messagetime = 0;
  1532. X    bigmessagetime = 0;
  1533. X    numlmessage = 0;
  1534. X    numfire = 0;
  1535. X    numfuel = 0;
  1536. X    numsweep = 0;
  1537. X    numguard = 0;
  1538. X    bonustimer = 20;
  1539. X    if(playerfuel < FUELCAPACITY / 2) playerfuel = FUELCAPACITY / 2;
  1540. X
  1541. X#ifndef    BLIT
  1542. X    init_zones();
  1543. X#endif
  1544. X
  1545. X}
  1546. X
  1547. X/*    reset_game just gives values to certain global variables that need to
  1548. X    be initialized for each game.
  1549. X*/
  1550. Xreset_game()
  1551. X{
  1552. X    dead = 0;
  1553. X    paused = 0;
  1554. X    score = 0;
  1555. X    men = 3;
  1556. X    playerfuel = FUELCAPACITY;
  1557. X    exploded = -1;
  1558. X    level = 1;
  1559. X    keyalive = 1;
  1560. X    extramaninc = 1;
  1561. X}
  1562. X
  1563. X/*    place_player puts the player and the door at maze location (x,y).
  1564. X*/
  1565. Xplace_player(x, y)
  1566. Xint    x, y;
  1567. X{
  1568. X    ply = (y + 1) * mazescale - 11;
  1569. X    plx = x * mazescale + mazescale / 2;
  1570. X    doorx = plx;
  1571. X    doory = ply;
  1572. X    exploded = -1;
  1573. X    walk = 1;
  1574. X    playervert = 0;
  1575. X    indoor = 1;
  1576. X    burn = 0;
  1577. X    playerdir = STOP;
  1578. X    playerphase = FACEFRONT;
  1579. X}
  1580. X
  1581. X/*    random_player puts the player and the door in a random maze location
  1582. X    with a floor.
  1583. X*/
  1584. Xrandom_player()
  1585. X{
  1586. X    register int    x, y;
  1587. X
  1588. X    do {
  1589. X        x = random() % mazewidth + 1;
  1590. X        y = random() % mazeheight + 1;
  1591. X    } while(!(maze[x][y] & WALLDOWN));
  1592. X    ply = (y + 1) * mazescale - 11;
  1593. X    plx = x * mazescale + mazescale / 2;
  1594. X    doorx = plx;
  1595. X    doory = ply;
  1596. X    exploded = -1;
  1597. X    walk = 1;
  1598. X    playervert = 0;
  1599. X    indoor = 1;
  1600. X    burn = 0;
  1601. X    playerdir = STOP;
  1602. X    playerphase = FACEFRONT;
  1603. X}
  1604. X
  1605. X/*    place_fireball puts a fireball at world position (x,y) with speed
  1606. X    [dx,dy]. The coordinates are modified to so the fireball won't sit on
  1607. X    a wall.
  1608. X*/
  1609. Xplace_fireball(x, y, dx, dy)
  1610. Xint    x, y, dx, dy;
  1611. X{
  1612. X    if(numfire == MAXFIREBALLS) return;
  1613. X    nx = x;
  1614. X    ny = y;
  1615. X    set_in_maze(FIREWIDTH / 2);
  1616. X    firex[numfire] = nx;
  1617. X    firey[numfire] = ny;
  1618. X    firedx[numfire] = dx;
  1619. X    firedy[numfire] = dy;
  1620. X    numfire++;
  1621. X}
  1622. X
  1623. X/*    random_fireballs puts num fireballs in the maze with speeds ranging
  1624. X    from min to max. The coordinates of each are generated so they won't
  1625. X    sit on a wall or are too close to the player.
  1626. X*/
  1627. Xrandom_fireballs(num, min, max)
  1628. Xint    num, min, max;
  1629. X{
  1630. X    register int    i;
  1631. X
  1632. X    if(num > MAXFIREBALLS) numfire = MAXFIREBALLS;
  1633. X    else numfire = num;
  1634. X    for(i=0; i<numfire; i++) {
  1635. X        do {
  1636. X            nx = random() % (mazewidth * mazescale) + mazescale;
  1637. X            ny = random() % (mazeheight * mazescale) + mazescale;
  1638. X            set_in_maze(FIREWIDTH / 2);
  1639. X        } while((plx - nx) * (plx - nx) + (ply - ny) * (ply - ny) < 40000);
  1640. X        firex[i] = nx;
  1641. X        firey[i] = ny;
  1642. X        do {
  1643. X            firedx[i] = random() % 21 - 10;
  1644. X            firedy[i] = random() % 21 - 10;
  1645. X        } while(((firedx[i] ==  0) && (firedy[i] == 0)) || (abs(firedx[i]) +
  1646. X                abs(firedy[i]) < min) || (abs(firedx[i]) + abs(firedy[i])
  1647. X                > max));
  1648. X        firephase[i] = random() % FIREPHASES;
  1649. X    }
  1650. X}
  1651. X
  1652. X/*    place_guard puts a guard at maze location (x,y) with direction dir and
  1653. X    speed speed
  1654. X*/
  1655. Xplace_guard(x, y, dir, speed)
  1656. Xint    x, y, dir, speed;
  1657. X{
  1658. X    if(numguard == MAXGUARDS) return;
  1659. X    guardx[numguard] = x * mazescale + mazescale / 2;
  1660. X    guardy[numguard] = y * mazescale + mazescale / 2;
  1661. X    guarddir[numguard] = dir;
  1662. X    guardspeed[numguard] = speed;
  1663. X    guardphase[numguard] = random() % GUARDPHASES;
  1664. X    guardtime[numguard] = 0;
  1665. X    numguard++;
  1666. X}
  1667. X
  1668. X/*    random_guards puts num guards in the maze with speeds ranging from min
  1669. X    to max. Guards are nor placed on the same square as the player.
  1670. X*/
  1671. Xrandom_guards(num, min, max)
  1672. Xint    num, min, max;
  1673. X{
  1674. X    register int    i, x, y, m;
  1675. X
  1676. X    if(num > MAXGUARDS) numguard = MAXGUARDS;
  1677. X    else numguard = num;
  1678. X    for(i=0; i<numguard; i++) {
  1679. X        do {
  1680. X            x = random() % mazewidth + 1;
  1681. X            y = random() % mazeheight + 1;
  1682. X        } while((x == plx / mazescale) && (y == ply / mazescale));
  1683. X        guardx[i] = x * mazescale + mazescale / 2;
  1684. X        guardy[i] = y * mazescale + mazescale / 2;
  1685. X        if(max > 9) m = 9;
  1686. X        else m = max;
  1687. X        guardspeed[i] = random() % (m - min + 1) + min;
  1688. X        guardphase[i] = random() % GUARDPHASES;
  1689. X        guardtime[i] = 0;
  1690. X        do {
  1691. X            guarddir[i] = random() % 4;
  1692. X        } while(maze[x][y] & walldir[guarddir[i]]);
  1693. X    }
  1694. X}
  1695. X
  1696. X/*    place_sweeper puts a sweeper at maze location (x,y) with a floor
  1697. X    direction of floor, rotation of rot, and speed speed
  1698. X*/
  1699. Xplace_sweeper(x, y, floor, rot, speed)
  1700. Xint    x, y, floor, rot, speed;
  1701. X{
  1702. X    if(numsweep == MAXSWEEPERS) return;
  1703. X    sweepx[numsweep] = x * mazescale + mazescale / 2 + xdir[floor] *
  1704. X                        (mazescale / 2 - 11);
  1705. X    sweepy[numsweep] = y * mazescale + mazescale / 2 + ydir[floor] *
  1706. X                        (mazescale / 2 - 11);
  1707. X    sweepfloor[numsweep] = floor;
  1708. X    if(rot == 1) {
  1709. X        if(floor == 0) sweepdir[numsweep] = 3;
  1710. X        else sweepdir[numsweep] = floor - 1;
  1711. X    } else {
  1712. X        if(floor == 3) sweepdir[numsweep] = 0;
  1713. X        else sweepdir[numsweep] = floor + 1;
  1714. X    }
  1715. X    sweeprot[numsweep] = rot;
  1716. X    sweepphase[numsweep] = random() % SWEEPERPHASES;
  1717. X    sweepspeed[numsweep] = speed;
  1718. X    numsweep++;
  1719. X}
  1720. X
  1721. X/*    random sweepers puts num sweepers in the maze with speeds from min to
  1722. X    max. Sweepers will not be placed in the same square as the player.
  1723. X*/
  1724. Xrandom_sweepers(num, min, max)
  1725. Xint    num, min, max;
  1726. X{
  1727. X    register int    i, x, y, dir, m;
  1728. X
  1729. X    if(num > MAXSWEEPERS) numsweep = MAXSWEEPERS;
  1730. X    else numsweep = num;
  1731. X    for(i=0; i<numsweep; i++) {
  1732. X        do {
  1733. X            do {
  1734. X                x = random() % mazewidth + 1;
  1735. X                y = random() % mazeheight + 1;
  1736. X            } while(!maze[x][y]);
  1737. X            do {
  1738. X                dir = random() % 4;
  1739. X            } while(!(maze[x][y] & walldir[dir]));
  1740. X            sweepx[i] = x * mazescale + mazescale / 2 + xdir[dir] *
  1741. X                        (mazescale / 2 - 11);
  1742. X            sweepy[i] = y * mazescale + mazescale / 2 + ydir[dir] *
  1743. X                        (mazescale / 2 - 11);
  1744. X            sweepfloor[i] = dir;
  1745. X            if(random() & 01) {
  1746. X                if(dir == 0) sweepdir[i] = 3;
  1747. X                else sweepdir[i] = dir - 1;
  1748. X                sweeprot[i] = 1;
  1749. X            } else {
  1750. X                if(dir == 3) sweepdir[i] = 0;
  1751. X                else sweepdir[i] = dir + 1;
  1752. X                sweeprot[i] = -1;
  1753. X            }
  1754. X        } while((plx / mazescale == sweepx[i]) &&
  1755. X                    (ply / mazescale == sweepy[i]));
  1756. X        sweepphase[i] = random() % SWEEPERPHASES;
  1757. X        if(max > 9) m = 9;
  1758. X        else m = max;
  1759. X        sweepspeed[i] = random() % (m - min + 1) + min;
  1760. X    }
  1761. X}
  1762. X
  1763. X/*    place_fuel puts a fuel pod at world location (x,y). The coordinates
  1764. X    are modified so the pod won't sit on a wall.
  1765. X*/
  1766. Xplace_fuel(x, y)
  1767. Xint x, y;
  1768. X{
  1769. X    if(numfuel == MAXFUELPODS) return;
  1770. X    nx = x;
  1771. X    ny = y;
  1772. X    set_in_maze(FUELWIDTH / 2);
  1773. X    fuelx[numfuel] = nx;
  1774. X    fuely[numfuel] = ny;
  1775. X    fuelalive[numfuel] = 1;
  1776. X    numfuel++;
  1777. X}
  1778. X
  1779. X/*    random_fuel places num fuel pods in the maze. The coordinates are
  1780. X    generated so they don't sit on walls or too close together.
  1781. X*/
  1782. Xrandom_fuel(num)
  1783. Xint    num;
  1784. X{
  1785. X    register int    i, j, ok, radius;
  1786. X
  1787. X    if(num > MAXFUELPODS) numfuel = MAXFUELPODS;
  1788. X    else numfuel = num;
  1789. X    if(numfuel == 0) return;
  1790. X    radius = (mazewidth * mazeheight * mazescale * mazescale) / (6 * numfuel);
  1791. X    for(i=0; i<numfuel; i++) {
  1792. X        do {
  1793. X            nx = random() % (mazewidth * mazescale) + mazescale;
  1794. X            ny = random() % (mazeheight * mazescale) + mazescale;
  1795. X        set_in_maze(FUELWIDTH / 2);
  1796. X        ok = 1;
  1797. X        for(j=0; j<i; j++) {
  1798. X            if((fuelx[j] - nx) * (fuelx[j] - nx) +
  1799. X                (fuely[j] - ny) * (fuely[j] - ny) < radius) ok = 0;
  1800. X        }
  1801. X        } while(!ok);
  1802. X        fuelx[i] = nx;
  1803. X        fuely[i] = ny;
  1804. X        fuelalive[i] = 1;
  1805. X    }
  1806. X}
  1807. X
  1808. X/*    place_key puts the key at world coordinates (x,y). The coordinates are
  1809. X    modified so the key will not sit on a wall.
  1810. X*/
  1811. Xplace_key(x, y)
  1812. Xint    x, y;
  1813. X{
  1814. X    nx = x;
  1815. X    ny = y;
  1816. X    set_in_maze(KEYWIDTH / 2);
  1817. X    keyx = nx;
  1818. X    keyy = ny;
  1819. X    keyalive = 1;
  1820. X}
  1821. X
  1822. X/*    random_key puts the key in a random location. The coordinates are
  1823. X    generated so the key won't be on a wall or close to the player.
  1824. X*/
  1825. Xrandom_key()
  1826. X{
  1827. X    register int    radius,dist;
  1828. X
  1829. X    if(mazewidth > mazeheight) {
  1830. X        if(plx > (mazewidth * mazescale) / 2) dist = plx;
  1831. X        else dist = mazewidth * mazescale - plx;
  1832. X    } else {
  1833. X        if(ply > (mazeheight * mazescale) / 2) dist = ply;
  1834. X        else dist = mazeheight * mazescale - ply;
  1835. X    }
  1836. X    radius = (dist * dist * 9) / 16;
  1837. X    do {
  1838. X        nx = random() % (mazewidth * mazescale) + mazescale;
  1839. X        ny = random() % (mazeheight * mazescale) + mazescale;
  1840. X    } while((plx - nx) * (plx - nx) + (ply - ny) * (ply - ny) < radius);
  1841. X    set_in_maze(KEYWIDTH / 2);
  1842. X    keyx = nx;
  1843. X    keyy = ny;
  1844. X    keyalive = 1;
  1845. X}
  1846. END_OF_FILE
  1847. if test 8638 -ne `wc -c <'setup.c'`; then
  1848.     echo shar: \"'setup.c'\" unpacked with wrong size!
  1849. fi
  1850. # end of 'setup.c'
  1851. fi
  1852. if test -f 'update.c' -a "${1}" != "-c" ; then 
  1853.   echo shar: Will not clobber existing file \"'update.c'\"
  1854. else
  1855. echo shar: Extracting \"'update.c'\" \(5977 characters\)
  1856. sed "s/^X//" >'update.c' <<'END_OF_FILE'
  1857. X/*    update.c : routines that update all the objects for each frame
  1858. X*/
  1859. X
  1860. X#include "copyright.h"
  1861. X#include "defs.h"
  1862. X
  1863. Xint    plx, ply, burn, playerphase, playerdir, playervert, playerfuel,
  1864. X    walk, waiting, exploded, explodetimer;
  1865. X
  1866. Xint    numfire;
  1867. Xint    firex[MAXFIREBALLS], firey[MAXFIREBALLS], firedx[MAXFIREBALLS],
  1868. X    firedy[MAXFIREBALLS], firephase[MAXFIREBALLS];
  1869. X
  1870. Xint    numfuel;
  1871. Xint    fuelx[MAXFUELPODS], fuely[MAXFUELPODS], fuelalive[MAXFUELPODS],
  1872. X    fueltimer[MAXFUELPODS];
  1873. X
  1874. Xint    numsweep;
  1875. Xint    sweepx[MAXSWEEPERS], sweepy[MAXSWEEPERS], sweepphase[MAXSWEEPERS],
  1876. X    sweepdir[MAXSWEEPERS], sweepfloor[MAXSWEEPERS], sweepspeed[MAXSWEEPERS],
  1877. X    sweeprot[MAXSWEEPERS];
  1878. X
  1879. Xint    numguard;
  1880. Xint    guardx[MAXGUARDS], guardy[MAXGUARDS], guarddir[MAXGUARDS],
  1881. X    guardspeed[MAXGUARDS], guardphase[MAXGUARDS], guardtime[MAXGUARDS];
  1882. X
  1883. Xint    keyx, keyy, keyalive, keytimer;
  1884. Xint    doorx, doory, indoor;
  1885. X
  1886. X/*    update does all the object updating
  1887. X*/
  1888. Xupdate()
  1889. X{
  1890. X    update_player();
  1891. X    update_fireballs();
  1892. X    update_sweepers();
  1893. X    update_guards();
  1894. X}
  1895. X
  1896. X/*    update_player updates the player
  1897. X*/
  1898. Xupdate_player()
  1899. X{
  1900. X    register int    flags;
  1901. X
  1902. X    if(dead) {
  1903. X        deadtimer--;
  1904. X        if(!deadtimer) game_over();
  1905. X        return;
  1906. X    }
  1907. X    if(waiting) {
  1908. X        waiting--;
  1909. X        score_bonus();
  1910. X        if(waiting == 0) {
  1911. X            leveldone = 1;
  1912. X            level++;
  1913. X            oldscore = -1;
  1914. X            oldlevel = -1;
  1915. X        }
  1916. X        return;
  1917. X    }
  1918. X    if(exploded > -1) {
  1919. X        explodetimer--;
  1920. X        if(explodetimer == 0) {
  1921. X            explodetimer = EXPLODETIME;
  1922. X            exploded++;
  1923. X            if(exploded >= EXPLODEFRAMES) {
  1924. X                death();
  1925. X            }
  1926. X        }
  1927. X        return;
  1928. X    }
  1929. X    nx = plx + PLAYERSPEED * playerdir;
  1930. X    ny = ply + playervert;
  1931. X    if(playerfuel <= 0) burn = 0;
  1932. X    playervert += GRAVITY + THRUST * burn;
  1933. X    playerfuel = playerfuel - BURNCOST * burn;
  1934. X    if(playervert > DOWNSPEED) playervert = DOWNSPEED;
  1935. X    if(playervert < UPSPEED) playervert = UPSPEED;
  1936. X    flags = set_in_maze(PLAYERWIDTH / 2);
  1937. X    if(flags & WALLDOWN) {
  1938. X        walk = 1;
  1939. X        if(playervert > 0) playervert = 0;
  1940. X    } else {
  1941. X        walk = 0;
  1942. X    }
  1943. X    if(flags & WALLUP) {
  1944. X        if(playervert < 0) playervert = 0;
  1945. X    }
  1946. X    plx = nx;
  1947. X    ply = ny;
  1948. X    if(!burn && walk && (playerdir != 0)) {
  1949. X        playerphase += playerdir;
  1950. X        if(playerphase > FACERIGHT - 1) playerphase = FACEFRONT + 1;
  1951. X        if(playerphase < FACELEFT + 1) playerphase = FACEFRONT - 1;
  1952. X        if((playerdir == 1) && (playerphase < FACEFRONT))
  1953. X            playerphase = FACEFRONT;
  1954. X        if((playerdir == -1) && (playerphase > FACEFRONT))
  1955. X            playerphase = FACEFRONT;
  1956. X    } else playerphase = (playerdir + 1) * FACEFRONT;
  1957. X    if((plx > doorx - 5) && (plx < doorx + 5) && (ply < doory + 5) &&
  1958. X        (ply > doory - 5) && walk) indoor = 1;
  1959. X    else indoor = 0;
  1960. X}
  1961. X
  1962. X/*    update_fireballs updates all the fireballs
  1963. X*/
  1964. Xupdate_fireballs()
  1965. X{
  1966. X    register int    i, flags;
  1967. X
  1968. X    for(i=0; i<numfire; i++) {
  1969. X        nx = firex[i] + firedx[i];
  1970. X        ny = firey[i] + firedy[i];
  1971. X        flags = set_in_maze(FIREWIDTH / 2);
  1972. X        if(flags & WALLRIGHT) if(firedx[i] > 0) firedx[i] = -firedx[i];
  1973. X        if(flags & WALLLEFT) if(firedx[i] < 0) firedx[i] = -firedx[i];
  1974. X        if(flags & WALLDOWN) if(firedy[i] > 0) firedy[i] = -firedy[i];
  1975. X        if(flags & WALLUP) if(firedy[i] < 0) firedy[i] = -firedy[i];
  1976. X        firex[i] = nx;
  1977. X        firey[i] = ny;
  1978. X        firephase[i] = random() % FIREPHASES;
  1979. X    }
  1980. X}
  1981. X
  1982. X/*    update_guards updates all the guards
  1983. X*/
  1984. Xupdate_guards()
  1985. X{
  1986. X    register int    i, dir, x, y, dx, dy, sp;
  1987. X
  1988. X    for(i=0; i<numguard; i++) {
  1989. X        guardtime[i]++;
  1990. X        if(guardtime[i] == 10) {
  1991. X            guardtime[i] = 0;
  1992. X            guardphase[i] = random() % GUARDPHASES;
  1993. X        }
  1994. X        dx = guardx[i] % mazescale;
  1995. X        dy = guardy[i] % mazescale;
  1996. X        sp = guardspeed[i] / 2 + 1;
  1997. X        if((dx > mazescale / 2 - sp) && (dx < mazescale / 2 + sp) &&
  1998. X            (dy > mazescale / 2 - sp) && (dy < mazescale / 2 + sp)) {
  1999. X                x = guardx[i] / mazescale;
  2000. X                y = guardy[i] / mazescale;
  2001. X                guardx[i] = x * mazescale + mazescale / 2;
  2002. X                guardy[i] = y * mazescale + mazescale / 2;
  2003. X                do {
  2004. X                    dir = random() % 4;
  2005. X                } while((walldir[dir] & maze[x][y]) ||
  2006. X                        ((walldir[dir] == oppdir[guarddir[i]]) &&
  2007. X                        !(maze[x][y] == ((WALLUP|WALLDOWN|WALLLEFT|WALLRIGHT)
  2008. X                        & ~(walldir[dir])))));
  2009. X                guarddir[i] = dir;
  2010. X        }
  2011. X        guardx[i] += guardspeed[i] * xdir[guarddir[i]];
  2012. X        guardy[i] += guardspeed[i] * ydir[guarddir[i]];
  2013. X    }
  2014. X}
  2015. X
  2016. X/*    update_sweepers updates all the sweepers
  2017. X*/
  2018. Xupdate_sweepers()
  2019. X{
  2020. X    register int    i, flags;
  2021. X
  2022. X    for(i=0; i<numsweep; i++) {
  2023. X        sweepphase[i] += sweeprot[i];
  2024. X        if(sweepphase[i] == SWEEPERPHASES) sweepphase[i] = 0;
  2025. X        if(sweepphase[i] < 0) sweepphase[i] = SWEEPERPHASES - 1;
  2026. X        nx = sweepx[i];
  2027. X        ny = sweepy[i];
  2028. X        if(!(maze[nx / mazescale][ny / mazescale] & walldir[sweepfloor[i]])) {
  2029. X            if(xdir[sweepfloor[i]] != 0) {
  2030. X                nx = (nx / mazescale + xdir[sweepfloor[i]]) * mazescale +
  2031. X                        mazescale / 2 - xdir[sweepfloor[i]] * mazescale / 2;
  2032. X            }
  2033. X            if(ydir[sweepfloor[i]] != 0) {
  2034. X            ny = (ny / mazescale + ydir[sweepfloor[i]]) * mazescale +
  2035. X                    mazescale / 2 - ydir[sweepfloor[i]] * mazescale / 2;
  2036. X            }
  2037. X            if(sweeprot[i] == 1) increment_sweepdir(i);
  2038. X            else decrement_sweepdir(i);
  2039. X        }
  2040. X        nx += xdir[sweepdir[i]] * sweepspeed[i];
  2041. X        ny += ydir[sweepdir[i]] * sweepspeed[i];
  2042. X        flags = set_in_maze(SWEEPERWIDTH / 2);
  2043. X        if(flags & WALLRIGHT) {
  2044. X            if(sweepdir[i] == 1) {
  2045. X                if(sweepfloor[i] == 2) decrement_sweepdir(i);
  2046. X                else increment_sweepdir(i);
  2047. X            }
  2048. X        }
  2049. X        if(flags & WALLLEFT) {
  2050. X            if(sweepdir[i] == 3) {
  2051. X                if(sweepfloor[i] == 0) decrement_sweepdir(i);
  2052. X                else increment_sweepdir(i);
  2053. X            }
  2054. X        }
  2055. X        if(flags & WALLUP) {
  2056. X            if(sweepdir[i] == 0) {
  2057. X                if(sweepfloor[i] == 1) decrement_sweepdir(i);
  2058. X                else increment_sweepdir(i);
  2059. X            }
  2060. X        }
  2061. X        if(flags & WALLDOWN) {
  2062. X            if(sweepdir[i] == 2) {
  2063. X                if(sweepfloor[i] == 3) decrement_sweepdir(i);
  2064. X                else increment_sweepdir(i);
  2065. X            }
  2066. X        }
  2067. X        sweepx[i] = nx;
  2068. X        sweepy[i] = ny;
  2069. X    }
  2070. X}
  2071. X
  2072. X/*    decrement_sweepdir does a circular decrement on sweeper i's direction
  2073. X*/
  2074. Xdecrement_sweepdir(i)
  2075. Xint i;
  2076. X{    
  2077. X    sweepdir[i]--;
  2078. X    if(sweepdir[i] < 0) sweepdir[i] = 3;
  2079. X    sweepfloor[i]--;
  2080. X    if(sweepfloor[i] < 0) sweepfloor[i] = 3;
  2081. X}
  2082. X
  2083. X/*    increment_sweepdir does a circular increment on sweeper i's direction
  2084. X*/
  2085. Xincrement_sweepdir(i)
  2086. Xint i;
  2087. X{    
  2088. X    sweepdir[i]++;
  2089. X    if(sweepdir[i] > 3) sweepdir[i] = 0;
  2090. X    sweepfloor[i]++;
  2091. X    if(sweepfloor[i] > 3) sweepfloor[i] = 0;
  2092. X}
  2093. END_OF_FILE
  2094. if test 5977 -ne `wc -c <'update.c'`; then
  2095.     echo shar: \"'update.c'\" unpacked with wrong size!
  2096. fi
  2097. # end of 'update.c'
  2098. fi
  2099. echo shar: End of archive 3 \(of 4\).
  2100. cp /dev/null ark3isdone
  2101. MISSING=""
  2102. for I in 1 2 3 4 ; do
  2103.     if test ! -f ark${I}isdone ; then
  2104.     MISSING="${MISSING} ${I}"
  2105.     fi
  2106. done
  2107. if test "${MISSING}" = "" ; then
  2108.     echo You have unpacked all 4 archives.
  2109.     rm -f ark[1-9]isdone
  2110. else
  2111.     echo You still need to unpack the following archives:
  2112.     echo "        " ${MISSING}
  2113. fi
  2114. ##  End of shell archive.
  2115. exit 0
  2116.