home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk1.iso / altsrc / articles / 11240 < prev    next >
Internet Message Format  |  1994-09-11  |  47KB

  1. Path: wupost!kuhub.cc.ukans.edu!nrlvx1.nrl.navy.mil!ra!news.pop.psu.edu!news.cac.psu.edu!howland.reston.ans.net!europa.eng.gtefsd.com!MathWorks.Com!news.duke.edu!godot.cc.duq.edu!newsfeed.pitt.edu!uunet!news.sprintlink.net!demon!hunting2.demon.co.uk!zondo
  2. Newsgroups: alt.sources
  3. Subject: Wander: puzzle game (1 of 6)
  4. Message-ID: <778924728snz@hunting2.demon.co.uk>
  5. From: zondo@hunting2.demon.co.uk (Zondo Pillock)
  6. Date: Wed, 7 Sep 1994 07:58:48 +0000
  7. Reply-To: zondo@hunting2.demon.co.uk
  8. Sender: usenet@demon.co.uk
  9. Organization: Hunting Engineering Limited
  10. X-Newsreader: Demon Internet Simple News v1.29
  11. Lines: 2028
  12.  
  13. This is wander, version 1.0.
  14.  
  15. Wander is a game where you wander around the screen collecting
  16. treasures, solving puzzles and avoiding the nasty monsters.  It's
  17. really a new version of an old game called 'wanderer', written by
  18. Steven Shipway back in 1988.  Ah, wanderer... excellent game, shame
  19. about the source code.  I loved the game so much I rewrote it to
  20. (hopefully) make it more slick and expandable.  See the file CHANGES
  21. for the main differences between this version and the old one.
  22.  
  23. Wander uses curses and has been tested on a DECstation 5000 (ULTRIX)
  24. and SGI Indigo (IRIX).
  25.  
  26.                                                                __o
  27.                                 zondo@hunting2.demon.co.uk   _`\<,_
  28.                                 ............................(_)/ (_)
  29.  
  30.  
  31. Submitted-by: zondo@hunting2.demon.co.uk
  32. Archive-name: wander/part01
  33.  
  34. ---- Cut Here and feed the following to sh ----
  35. #!/bin/sh
  36. # This is wander, a shell archive (produced by GNU shar 4.0)
  37. # To extract the files from this archive, save it to some FILE, remove
  38. # everything before the `!/bin/sh' line above, then type `sh FILE'.
  39. #
  40. # Made on 1994-09-07 08:32 BST by <zondo@hunting2.demon.co.uk>.
  41. # Source directory was `/ss/glen/files/cprogs/wander'.
  42. #
  43. # Existing files will *not* be overwritten unless `-c' is specified.
  44. #
  45. # This shar contains:
  46. # length mode       name
  47. # ------ ---------- ------------------------------------------
  48. #   5023 -r--r--r-- Makefile
  49. #   8612 -r--r--r-- main.c
  50. #   7220 -r--r--r-- pos.c
  51. #   4266 -r--r--r-- mon.c
  52. #  12690 -r--r--r-- draw.c
  53. #  11194 -r--r--r-- move.c
  54. #   5452 -r--r--r-- score.c
  55. #   5346 -r--r--r-- save.c
  56. #   1318 -r--r--r-- keys.c
  57. #   1987 -r--r--r-- timer.c
  58. #   1983 -r--r--r-- help.c
  59. #   3094 -r--r--r-- will.c
  60. #   2846 -r--r--r-- misc.c
  61. #   2998 -r--r--r-- defs.h
  62. #   4115 -r--r--r-- data.h
  63. #   5552 -r--r--r-- effect.h
  64. #    783 -r--r--r-- config.h
  65. #   2569 -rw-r--r-- proto.h
  66. #    367 -r--r--r-- version.h
  67. #   5756 -rw-r--r-- README
  68. #    758 -rw-r--r-- CHANGES
  69. #  12488 -rw-r--r-- COPYING
  70. #   8280 -r--r--r-- wander.doc
  71. #   6699 -rw-rw-r-- wander.man
  72. #   7968 -rw-rw-r-- wander.txt
  73. #   1163 -r--r--r-- cmds.help
  74. #   1526 -r--r--r-- full.help
  75. #    691 -r--r--r-- mini.help
  76. #    702 -rw-r--r-- screens/screen.1
  77. #    700 -rw-r--r-- screens/screen.10
  78. #    700 -rw-r--r-- screens/screen.11
  79. #    700 -rw-r--r-- screens/screen.12
  80. #    701 -rw-r--r-- screens/screen.2
  81. #    701 -rw-r--r-- screens/screen.3
  82. #    700 -rw-r--r-- screens/screen.4
  83. #    700 -rw-r--r-- screens/screen.5
  84. #    702 -rw-r--r-- screens/screen.6
  85. #    700 -rw-r--r-- screens/screen.7
  86. #    700 -rw-r--r-- screens/screen.8
  87. #    702 -rw-r--r-- screens/screen.9
  88. #    351 -rw-r--r-- sol/sol.4
  89. #    500 -rw-r--r-- sol/sol.6
  90. #    244 -rw-r--r-- sol/sol.7
  91. #    785 -rw-r--r-- sol/sol.9
  92. #    472 -rw-r--r-- sol/sol.1
  93. #    575 -rw-r--r-- sol/sol.3
  94. #    660 -rw-r--r-- sol/sol.5
  95. #    450 -rw-r--r-- sol/sol.10
  96. #    926 -rw-r--r-- sol/sol.11
  97. #    617 -rw-r--r-- sol/sol.12
  98. #    473 -rw-r--r-- sol/sol.2
  99. #    258 -rw-r--r-- sol/sol.8
  100. #   3341 -rw-r--r-- icons/backslide_bm
  101. #   3329 -rw-r--r-- icons/brick_bm
  102. #   3326 -rw-r--r-- icons/cage_bm
  103. #   3335 -rw-r--r-- icons/diamond_bm
  104. #   3326 -rw-r--r-- icons/dirt_bm
  105. #   3338 -rw-r--r-- icons/fwdslide_bm
  106. #   3296 -rw-r--r-- icons/landmine_bm
  107. #   3332 -rw-r--r-- icons/larrow_bm
  108. #   3335 -rw-r--r-- icons/monster_bm
  109. #   3290 -rw-r--r-- icons/player_bm
  110. #   3378 -rw-r--r-- icons/playerl_bm
  111. #   3293 -rw-r--r-- icons/playerr_bm
  112. #   3332 -rw-r--r-- icons/rarrow_bm
  113. #   3326 -rw-r--r-- icons/rock_bm
  114. #   3329 -rw-r--r-- icons/space_bm
  115. #   3332 -rw-r--r-- icons/sprite_bm
  116. #   3296 -rw-r--r-- icons/teleport_bm
  117. #   3347 -rw-r--r-- icons/timecapsule_bm
  118. #   3326 -rw-r--r-- icons/wall_bm
  119. #   3338 -rw-r--r-- icons/wanderer_bm
  120. #   3332 -rw-r--r-- icons/wayout_bm
  121. #   3332 -rw-r--r-- icons/whoops_bm
  122. #    304 -rw-r--r-- icons/backslide_tbm
  123. #    292 -rw-r--r-- icons/brick_tbm
  124. #    289 -rw-r--r-- icons/cage_tbm
  125. #    298 -rw-r--r-- icons/diamond_tbm
  126. #    289 -rw-r--r-- icons/dirt_tbm
  127. #    301 -rw-r--r-- icons/fwdslide_tbm
  128. #    299 -rw-r--r-- icons/landmine_tbm
  129. #    295 -rw-r--r-- icons/larrow_tbm
  130. #    298 -rw-r--r-- icons/monster_tbm
  131. #    295 -rw-r--r-- icons/player_tbm
  132. #    295 -rw-r--r-- icons/rarrow_tbm
  133. #    289 -rw-r--r-- icons/rock_tbm
  134. #    292 -rw-r--r-- icons/space_tbm
  135. #    295 -rw-r--r-- icons/sprite_tbm
  136. #    299 -rw-r--r-- icons/teleport_tbm
  137. #    310 -rw-r--r-- icons/timecapsule_tbm
  138. #    289 -rw-r--r-- icons/wall_tbm
  139. #    295 -rw-r--r-- icons/wayout_tbm
  140. #    295 -rw-r--r-- icons/whoops_tbm
  141. #    147 -rw-rw-r-- icons/README
  142. #
  143. touch -am 1231235999 $$.touch >/dev/null 2>&1
  144. if test ! -f 1231235999 && test -f $$.touch; then
  145.   shar_touch=touch
  146. else
  147.   shar_touch=:
  148.   echo 'WARNING: not restoring timestamps'
  149. fi
  150. rm -f 1231235999 $$.touch
  151. #
  152. # ============= Makefile ==============
  153. if test -f 'Makefile' && test X"$1" != X"-c"; then
  154.   echo 'x - skipping Makefile (File already exists)'
  155. else
  156.   echo 'x - extracting Makefile (text)'
  157.   sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
  158. # Makefile for wander
  159. X
  160. # -------------------------- CUSTOMIZATION SECTION --------------------------
  161. X
  162. # Where to put the executable.
  163. BINDIR        = /work/bin
  164. X
  165. # Where to put the man page.
  166. MANDIR        = /work/man/man6
  167. X
  168. # Where you want the library files to live.
  169. LIBDIR        = /netdat/data/wander
  170. X
  171. # If you're on one of the predefined systems below, you're in luck.
  172. # Just type the associated command to make the program.  Otherwise
  173. # you'll have to continue customizing.
  174. #
  175. # DEC Ultrix            make dec
  176. # Silicon Graphics SGI        make sgi
  177. X
  178. # Your system type (currently either BSD42 or SYSVR3).
  179. SYSTEM        = BSD42
  180. #SYSTEM        = SYSVR3
  181. X
  182. # Type of curses library you're using (either BSD curses or X curses).
  183. # BSD curses has no attribute modes (apart from standout), so it's
  184. # preferable to use X curses if you have it.
  185. CURSES        = BSDCURSES
  186. #CURSES        = XCURSES
  187. X
  188. # Uncomment this if your version of curses has provision for extended
  189. # character sets.  BSD curses doesn't, nor do some versions of X curses
  190. # (my Ultrix implementation doesn't, anyway).
  191. #XCHARS        = -DXCHARS
  192. X
  193. # Name of your curses library.  Some systems (well, Ultrix anyway)
  194. # have both BSD and X curses, so the names may be slightly different.
  195. CURSESLIB     = curses
  196. #CURSESLIB     = cursesX
  197. X
  198. # Extra compilation flags
  199. FLAGS         = -g
  200. X
  201. # ---------------------- END OF CUSTOMIZATION SECTION -----------------------
  202. X
  203. SRCS          = main.c pos.c mon.c draw.c move.c score.c save.c \
  204. X                keys.c timer.c help.c will.c misc.c
  205. X
  206. OBJS          = main.o pos.o mon.o draw.o move.o score.o save.o \
  207. X                keys.o timer.o help.o will.o misc.o
  208. X
  209. HDRS          = defs.h data.h effect.h config.h proto.h version.h
  210. X
  211. DEFS          = -D$(SYSTEM) -D$(CURSES) $(XCHARS) -DLIBDIR=\"$(LIBDIR)\"
  212. X
  213. DOCS          = README CHANGES COPYING wander.doc wander.man wander.txt \
  214. X                cmds.help full.help mini.help
  215. X
  216. CFLAGS        = $(FLAGS) $(DEFS)
  217. X
  218. LOADLIBES     = -l$(CURSESLIB) -ltermcap
  219. X
  220. # ---------------------------- Main program ----------------------------
  221. X
  222. all:        wander
  223. X
  224. wander:        $(OBJS)
  225. X        cc -o wander $(OBJS) $(LDFLAGS) $(LOADLIBES)
  226. X
  227. # --------------------------- Specific systems -------------------------
  228. X
  229. dec:;        @make SYSTEM=BSD42     \
  230. X              XCHARS=          \
  231. X              CURSES=XCURSES   \
  232. X              CURSESLIB=cursesX
  233. X
  234. sgi:;        @make SYSTEM=SYSVR3    \
  235. X              XCHARS=-DXCHARS  \
  236. X              CURSES=XCURSES   \
  237. X              CURSESLIB=curses
  238. X
  239. # ---------------------------- Documentation ---------------------------
  240. X
  241. MKMAN         = sed -e "s^%%LIBDIR%%^$(LIBDIR)^"
  242. X
  243. wander.man:    wander.doc
  244. X        srctoman - wander.doc > wander.man
  245. X
  246. wander.txt:    wander.man
  247. X        tbl wander.man | nroff -man > wander.txt
  248. X
  249. # ---------------------------- Installation ----------------------------
  250. X
  251. install-bsd:    install-prog install-man install-data install-help
  252. X
  253. install-sysv:    install-prog install-catman install-data install-help
  254. X
  255. install-prog:    wander
  256. X        cp wander $(BINDIR)
  257. X        strip $(BINDIR)/wander
  258. X        chmod 711 $(BINDIR)/wander
  259. X
  260. install-man:    wander.man
  261. X        $(MKMAN) wander.man > $(MANDIR)/wander.6
  262. X
  263. install-catman:    wander.txt
  264. X        $(MKMAN) wander.txt > $(MANDIR)/wander
  265. X        rm -f $(MANDIR)/wander.z
  266. X        pack -f $(MANDIR)/wander
  267. X
  268. install-data:
  269. X        -mkdir $(LIBDIR)
  270. X        -mkdir $(LIBDIR)/screens
  271. X        cp screens/* $(LIBDIR)/screens
  272. X        chmod 644 $(LIBDIR)/screens/*
  273. X        touch $(LIBDIR)/scores
  274. X        chmod 666 $(LIBDIR)/scores
  275. X
  276. install-help:
  277. X        -mkdir $(LIBDIR)
  278. X        cp *.help $(LIBDIR)
  279. X        chmod 644 $(LIBDIR)/*.help
  280. X
  281. install-sol:
  282. X        -mkdir $(LIBDIR)
  283. X        -mkdir $(LIBDIR)/sol
  284. X        cp sol/* $(LIBDIR)/sol
  285. X        chmod 644 $(LIBDIR)/sol/*
  286. X
  287. # ---------------------- Miscellaneous other stuff -------------------
  288. X
  289. proto:;        cproto $(DEFS) -F"int\tmain(a, b)" $(SRCS) > proto.h
  290. X        @make wander
  291. X
  292. tags:        TAGS
  293. X
  294. TAGS:        $(SRCS) $(HDRS)
  295. X        etags $(SRCS) $(HDRS)
  296. X
  297. depend:        $(SRCS)
  298. X        mkdep $(CFLAGS) $(SRCS)
  299. X
  300. clean:;        rm -f wander $(OBJS)
  301. X
  302. lint:;        lint -habx $(DEFS) $(SRCS)
  303. X
  304. # ---------------------------- Distribution --------------------------
  305. X
  306. NETNAME       = zondo@hunting2.demon.co.uk
  307. X
  308. SHARDIR       = /work/pc
  309. SHARNAME      = wshar
  310. SHAROPTS      = -n wander -o $(SHARNAME) -l 50 -s $(NETNAME) -acT
  311. SHAR          = Makefile $(SRCS) $(HDRS) $(DOCS) screens sol icons
  312. X
  313. shar:        SHAR $(SHAR)
  314. X        shar $(SHAROPTS) $(SHAR)
  315. X        for i in $(SHARNAME)*; do \
  316. X            cat SHAR $$i > $(SHARDIR)/$$i; \
  317. X            rm $$i; \
  318. X        done        
  319. X
  320. # --------------------------- Dependencies ---------------------------
  321. X
  322. # DO NOT DELETE THIS LINE -- mkdep uses it.
  323. # DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
  324. X
  325. main.o: main.c defs.h data.h proto.h config.h version.h
  326. pos.o: pos.c defs.h data.h proto.h config.h
  327. mon.o: mon.c defs.h data.h proto.h config.h
  328. draw.o: draw.c defs.h data.h effect.h proto.h config.h
  329. move.o: move.c defs.h data.h proto.h config.h
  330. score.o: score.c defs.h data.h proto.h config.h
  331. save.o: save.c defs.h data.h proto.h config.h
  332. keys.o: keys.c defs.h
  333. timer.o: timer.c defs.h
  334. help.o: help.c defs.h data.h proto.h config.h
  335. will.o: will.c config.h
  336. misc.o: misc.c defs.h data.h proto.h config.h
  337. X
  338. # IF YOU PUT ANYTHING HERE IT WILL GO AWAY
  339. SHAR_EOF
  340.   $shar_touch -am 0907082494 'Makefile' &&
  341.   chmod 0444 'Makefile' ||
  342.   echo 'restore of Makefile failed'
  343.   shar_count="`wc -c < 'Makefile'`"
  344.   test 5023 -eq "$shar_count" ||
  345.     echo "Makefile: original size 5023, current size $shar_count"
  346. fi
  347. # ============= main.c ==============
  348. if test -f 'main.c' && test X"$1" != X"-c"; then
  349.   echo 'x - skipping main.c (File already exists)'
  350. else
  351.   echo 'x - extracting main.c (text)'
  352.   sed 's/^X//' << 'SHAR_EOF' > 'main.c' &&
  353. /*
  354. X *  Wander version 1.0, Copyright (C) 1994 G. Hutchings
  355. X *  Wander comes with ABSOLUTELY NO WARRANTY.
  356. X *  This is free software, and you are welcome to redistribute it
  357. X *  under certain conditions; see the file COPYING for details.
  358. X */
  359. X
  360. /* Main routine */
  361. X
  362. #ifndef lint
  363. static char rcsid[] = "$Id: main.c,v 1.37 1994/06/29 14:27:40 glen Exp $";
  364. #endif
  365. X
  366. #define MAIN
  367. X
  368. #include <stdio.h>
  369. #include <stdarg.h>
  370. #include "defs.h"
  371. #include "data.h"
  372. #include "proto.h"
  373. #include "config.h"
  374. #include "version.h"
  375. X
  376. char progname[BUFSIZ];        /* Duhh... guess what */
  377. char myname[BUFSIZ];        /* Your player name */
  378. X
  379. int
  380. main(int argc, char *argv[])
  381. {
  382. X    int scoretable = 0;        /* Display score table? */
  383. X    int levelscores = 0;    /* Display your level scores? */
  384. X    int levelset = 0;        /* Have you specified your level? */
  385. X    int letmebewiz = 0;        /* Do you want to be wizard? */
  386. X
  387. X    char buf[BUFSIZ], *getenv(char *name), *opts;
  388. X    extern int opterr, optind;
  389. X    extern char *optarg;
  390. X    int c, canbewiz;
  391. X
  392. X    /* Randomize */
  393. X    RANDINIT;
  394. X
  395. X    /* Who am I? */
  396. X    strcpy(progname, argv[0]);
  397. X
  398. X    /* Who are you? */
  399. X    strcpy(myname, playername());
  400. X
  401. X    /* Check wizard status */
  402. X    myuid = userid();
  403. X    canbewiz = (myuid == WIZUID);
  404. X
  405. X    /* Parse options */
  406. X    opts = getenv("WANDEROPTS");
  407. X    while (opts != NULL && *opts != '\0') {
  408. X    switch (*opts) {
  409. X    case 'b':
  410. X        if (*++opts != '\0')
  411. X        bordersize = *opts-'0';
  412. X        else
  413. X        fatal("`b' requires digit argument in WANDEROPTS");
  414. X        break;
  415. X    case 'h':
  416. X        hidescore = 1;
  417. X        break;
  418. X    case 'x':
  419. X        xchars = 1;
  420. X        break;
  421. X    }
  422. X
  423. X    opts++;
  424. X    }
  425. X
  426. X    /* Parse arguments */
  427. X    opterr = 0;
  428. X    while ((c = getopt(argc, argv, "b:l:svwxS")) != EOF) {
  429. X    switch (c) {
  430. X    case 'b':
  431. X        bordersize = atoi(optarg);
  432. X        break;
  433. X    case 'l':
  434. X        level = atoi(optarg);
  435. X        levelset = 1;
  436. X        break;
  437. X    case 's':
  438. X        levelscores = 1;
  439. X        break;
  440. X    case 'S':
  441. X        scoretable = 1;
  442. X        break;
  443. X    case 'v':
  444. X        printf(vformat, version);
  445. X        exit(0);
  446. X    case 'w':
  447. X        letmebewiz = 1;
  448. X        break;
  449. X    case 'x':
  450. X        xchars = !xchars;
  451. X        break;
  452. X    default:
  453. X        usage();
  454. X        break;
  455. X    }
  456. X    }
  457. X
  458. X    /* Last argument (if any) is a level test file */
  459. X    if (optind != argc) leveltest(argv[optind]);
  460. X
  461. X    /* Check for becoming wizard */
  462. X    if (letmebewiz) {
  463. X    if (!canbewiz) {
  464. X        printf("Magic wizzy password: ");
  465. X        gets(buf);
  466. X        canbewiz = !strcmp(buf, WIZWORD);
  467. X    }
  468. X
  469. X    if (canbewiz) {
  470. X        wizard = 1;
  471. X        minidisplay = 1;
  472. X    } else {
  473. X        printf("Thou art not worthy, thou %s!\n", willie_phrase());
  474. X        endscreen();
  475. X        exit(0);
  476. X    }
  477. X    }
  478. X
  479. X    /* Get no. of available levels */
  480. X    nlevels = numlevels();
  481. X    if (nlevels == 0) {
  482. X    if (!wizard)
  483. X        fatal("can't find screen files!");
  484. X    else
  485. X        fatal("no screen files below this directory");
  486. X    }
  487. X
  488. X    /* Read current scores */
  489. X    readscores();
  490. X
  491. X    /* Show scores and exit if required */
  492. X    if (scoretable) {
  493. X    showscores();
  494. X    exit(0);
  495. X    }
  496. X
  497. X    if (levelscores) {
  498. X    showlevels(myuid);
  499. X    exit(0);
  500. X    }
  501. X
  502. X    /* Set level if not yet specified */
  503. X    maxlevel = getlevel(myuid);
  504. X    if (!levelset)
  505. X    level = (maxlevel > nlevels ? nlevels : maxlevel);
  506. X
  507. X    /* Check valid level */
  508. X    if (level <= 0) {
  509. X    printf("Invalid level, thou %s!\n", willie_phrase());
  510. X    exit(0);
  511. X    } else if (level > nlevels) {
  512. X    printf("There are only %d levels to play, thou %s!\n",
  513. X           nlevels, willie_phrase());
  514. X    exit(0);
  515. X    } else if (level > maxlevel && !wizard) {
  516. X    printf("You can't play level %d - you haven't done level %d yet!\n",
  517. X           level, maxlevel);
  518. X    exit(0);
  519. X    }
  520. X
  521. X    donelevel = (level < maxlevel);
  522. X
  523. X    /* Start up screen stuff */
  524. X    initscreen();
  525. X
  526. X    /* Play levels */
  527. X    while (1) {
  528. X    /* Read new level from file */
  529. X    curpos = readpos(level);
  530. X
  531. X    /* Play it */
  532. X    if (playscreen()) {
  533. X        /* Go to next level */
  534. X        level++;
  535. X        if (level > maxlevel) maxlevel = level;
  536. X        donelevel = (level < maxlevel);
  537. X
  538. X        /* Has player done the lot? */
  539. X        if (level > nlevels) {
  540. X        doeffect(curpos->pline, curpos->pcol, WINNER);
  541. X        endscreen();
  542. X        return 0;
  543. X        }
  544. X    } else {
  545. X        /* Quitted */
  546. X        doeffect(curpos->pline, curpos->pcol, GAVEUP);
  547. X        endscreen();
  548. X        return 0;
  549. X    }
  550. X    }
  551. X
  552. X    /* NOTREACHED */
  553. }
  554. X
  555. /* Play the current screen */
  556. int
  557. playscreen()
  558. {
  559. X    int cmd, nextlevel = 0, jump;
  560. X    char buf[BUFSIZ], *reply;
  561. X
  562. X    /* Initialise */
  563. X    initpos();
  564. X    recentre();
  565. X    exited = 0;
  566. X
  567. X    /* Appear on the screen */
  568. X    curpos->dead = 1;        /* for first picture - no player */
  569. X    drawpos(curpos);
  570. X    doeffect(curpos->pline, curpos->pcol, APPEAR);
  571. X    drawpos(curpos);
  572. X    curpos->dead = 0;
  573. X
  574. X    while (!nextlevel) {
  575. X    /* Scroll screen if required */
  576. X    scroll();
  577. X
  578. X    /* Draw current position */
  579. X    drawpos(curpos);
  580. X
  581. X    /* Get keypress */
  582. X    cmd = keypress();
  583. X
  584. X    /* Do the command */
  585. X    switch (cmd) {
  586. X    case QUIT:
  587. X        if (query("Really quit? ", 0)) return 0;
  588. X        break;
  589. X    case STAYPUT:
  590. X    case GONORTH:
  591. X    case GOEAST:
  592. X    case GOSOUTH:
  593. X    case GOWEST:
  594. X        movecmd(cmd);
  595. X        break;
  596. X    case BACKWARD:
  597. X        if (!exited && (wizard || donelevel)) backpos();
  598. X        break;
  599. X    case FORWARD:
  600. X        if (!exited && (wizard || donelevel)) forwardpos();
  601. X        break;
  602. X    case RESTART:
  603. X        if (curpos->dead || query("Restart this screen? ", 0)) {
  604. X        curpos = firstpos;
  605. X        exited = 0;
  606. X        recentre();
  607. X        }
  608. X        break;
  609. X    case FIRSTPOS:
  610. X        if (!exited && (wizard || donelevel)) {
  611. X        curpos = firstpos;
  612. X        recentre();
  613. X        }
  614. X        break;
  615. X    case LASTPOS:
  616. X        if (!exited && (wizard || donelevel)) {
  617. X        curpos = lastpos;
  618. X        recentre();
  619. X        }
  620. X        break;
  621. X    case JUMPLEVEL:
  622. X        if (wizard && !testlevel) {
  623. X        sprintf(buf, "Level to jump to (1-%d): ", nlevels);
  624. X        if ((reply = getstring(buf)) == NULL) break;
  625. X        jump = atoi(reply);
  626. X        if (jump == 0) break;
  627. X        if (jump >= 1 && jump <= nlevels) {
  628. X            level = jump;
  629. X            curpos = readpos(level);
  630. X            initpos();
  631. X            recentre();
  632. X            exited = 0;
  633. X        } else {
  634. X            message("Thou %s!", willie_phrase());
  635. X            beep();
  636. X        }
  637. X        }
  638. X        break;
  639. X    case SAVE:
  640. X        if (exited || donelevel || wizard) {
  641. X        save();
  642. X        } else {
  643. X        message("You haven't finished the level yet!");
  644. X        beep();
  645. X        }
  646. X        break;
  647. X    case RESTORE:
  648. X        if (donelevel || wizard) {
  649. X        restore();
  650. X        } else {
  651. X        message("Can't restore to this level");
  652. X        beep();
  653. X        }
  654. X        break;
  655. X    case NEXTLEVEL:
  656. X        if (exited) {
  657. X        nextlevel = 1;
  658. X        } else {
  659. X        message("You haven't finished the level yet!");
  660. X        beep();
  661. X        }
  662. X        break;
  663. X    case TOGGLEWIN:
  664. X        if (wizard) {
  665. X        minidisplay = !minidisplay;
  666. X        } else {
  667. X        minidisplay = 1;
  668. X        message("Type %c for help, any other to return", DISPHELP);
  669. X        drawpos(curpos);
  670. X
  671. X        while ((cmd = keypress()) == DISPHELP) {
  672. X            displayinfo();
  673. X            drawpos(curpos);
  674. X        }
  675. X
  676. X        minidisplay = 0;
  677. X        }
  678. X
  679. X        recentre();
  680. X        break;
  681. X    case SOLUTION:
  682. X        if (!testlevel) showsolution();
  683. X        break;
  684. X    case RECENTRE:
  685. X        recentre();
  686. X        break;
  687. X    case REDRAW:
  688. X        redraw();
  689. X        break;
  690. X    case CMDHELP:
  691. X        cmdinfo();
  692. X        break;
  693. X    case DISPHELP:
  694. X        displayinfo();
  695. X        break;
  696. X    default:
  697. X        message("Type ? for help");
  698. X        beep();
  699. X        break;
  700. X    }
  701. X    }
  702. X
  703. X    return 1;
  704. }
  705. X
  706. /* Process a move command */
  707. void
  708. movecmd(int cmd)
  709. {
  710. X    int dir;
  711. X
  712. X    if (exited) {
  713. X    message("You've finished this level - type %c to go to the next one",
  714. X        NEXTLEVEL);
  715. X    return;
  716. X    }
  717. X
  718. X    if (curpos->dead) {
  719. X    message("You're dead - type %c to restart the level", RESTART);
  720. X    return;
  721. X    }
  722. X
  723. X    switch (cmd) {
  724. X    case STAYPUT:
  725. X    dir = NONE;
  726. X    break;
  727. X    case GONORTH:
  728. X    dir = NORTH;
  729. X    break;
  730. X    case GOSOUTH:
  731. X    dir = SOUTH;
  732. X    break;
  733. X    case GOEAST:
  734. X    dir = EAST;
  735. X    break;
  736. X    case GOWEST:
  737. X    dir = WEST;
  738. X    break;
  739. X    }
  740. X
  741. X    if (canmove(dir)) domove(dir);
  742. }
  743. X
  744. /* Test out a level file */
  745. void
  746. leveltest(char *path)
  747. {
  748. X    /* Let them be wizard */
  749. X    wizard = 1;
  750. X    testlevel = 1;
  751. X    minidisplay = 1;
  752. X
  753. X    /* Start up screen stuff */
  754. X    initscreen();
  755. X
  756. X    /* Read new level from file */
  757. X    curpos = readposfile(path);
  758. X
  759. X    /* Play the level */
  760. X    playscreen();
  761. X
  762. X    /* Finish up */
  763. X    endscreen();
  764. X    exit(0);
  765. }
  766. X
  767. /* Give a fatal error */
  768. void
  769. fatal(char *fmt, ...)
  770. {
  771. X    va_list args;
  772. X
  773. X    endscreen();
  774. X    fprintf(stderr, "%s: Fatal: ", progname);
  775. X    va_start(args, fmt);
  776. X    vfprintf(stderr, fmt, args);
  777. X    fprintf(stderr, "\n");
  778. X    va_end(args);
  779. X    exit(1);
  780. }
  781. X
  782. /* Print usage message */
  783. void
  784. usage()
  785. {
  786. X    printf("Usage: %s [options]\n\n", progname);
  787. X    printf("-l level\tstart at specified level\n");
  788. X    printf("-b size\t\tset scroll border size\n");
  789. X    printf("-x\t\tuse extended display characters\n");
  790. X    printf("-w\t\tenter wizard mode\n");
  791. X    printf("-v\t\tprint program version\n");
  792. X    printf("-s\t\tshow your scores per level\n");
  793. X    printf("-S\t\tshow total scores\n");
  794. X    exit(0);
  795. }
  796. SHAR_EOF
  797.   $shar_touch -am 0629152894 'main.c' &&
  798.   chmod 0444 'main.c' ||
  799.   echo 'restore of main.c failed'
  800.   shar_count="`wc -c < 'main.c'`"
  801.   test 8612 -eq "$shar_count" ||
  802.     echo "main.c: original size 8612, current size $shar_count"
  803. fi
  804. # ============= pos.c ==============
  805. if test -f 'pos.c' && test X"$1" != X"-c"; then
  806.   echo 'x - skipping pos.c (File already exists)'
  807. else
  808.   echo 'x - extracting pos.c (text)'
  809.   sed 's/^X//' << 'SHAR_EOF' > 'pos.c' &&
  810. /*
  811. X *  Wander version 1.0, Copyright (C) 1994 G. Hutchings
  812. X *  Wander comes with ABSOLUTELY NO WARRANTY.
  813. X *  This is free software, and you are welcome to redistribute it
  814. X *  under certain conditions; see the file COPYING for details.
  815. X */
  816. X
  817. /* Position stack functions */
  818. X
  819. #ifndef lint
  820. static char rcsid[] = "$Id: pos.c,v 1.11 1994/06/16 15:38:58 glen Exp $";
  821. #endif
  822. X
  823. #include <stdio.h>
  824. #include "defs.h"
  825. #include "data.h"
  826. #include "proto.h"
  827. #include "config.h"
  828. X
  829. /* Read and return a new screen position */
  830. struct pos *
  831. readpos(int num)
  832. {
  833. X    return readposfile(levelpath(num));
  834. }
  835. X
  836. /* Read and return a new screen position from a file */
  837. struct pos *
  838. readposfile(char *path)
  839. {
  840. X    int nbaby = 0, ncage = 0, ndiamonds = 0, nexit = 0;
  841. X    int teleport = 0, tfound = 0, nmonsters = 0;
  842. X    int pline, pcol, pfound = 0, nmoves;
  843. X    int **screen, nlin = 0, ncol = 0;
  844. X    int ll[MAXHEIGHT], i, j, len;
  845. X    char buf[BUFSIZ];
  846. X    struct pos *p;
  847. X    FILE *fp;
  848. X
  849. X    /* Open file and read header */
  850. X    if ((fp = fopen(path, "r")) == NULL)
  851. X    fatal("Can't open %s", path);
  852. X
  853. X    if (fgets(buf, BUFSIZ, fp) == NULL)
  854. X    fatal("Error reading %s", path);
  855. X    if (sscanf(buf, "%d", &nmoves) != 1)
  856. X    fatal("Can't find move limit in %s", path);
  857. X
  858. X    /* Read screen data */
  859. X    screen = ALLOC(int *, MAXHEIGHT);
  860. X    while (fgets(buf, BUFSIZ, fp) != NULL) {
  861. X    len = strlen(buf)-1;
  862. X    buf[len] = NULL;    /* strip trailing newline */
  863. X    ll[nlin] = len;
  864. X    screen[nlin] = ALLOC(int, len);
  865. X    for (i = 0; i < len; i++) screen[nlin][i] = lookup(buf[i]);
  866. X    if (ncol < len) ncol = len;
  867. X    nlin++;
  868. X    }
  869. X
  870. X    fclose(fp);
  871. X    if (ncol < MINWIDTH || nlin < MINHEIGHT)
  872. X    fatal("%dx%d screen in %s is too small", ncol, nlin, path);
  873. X    if (ncol > MAXWIDTH || nlin > MAXHEIGHT)
  874. X    fatal("%dx%d screen in %s is too big", ncol, nlin, path);
  875. X
  876. X    /* Pad out rows to max row length */
  877. X    for (i = 0; i < nlin; i++) {
  878. X    if (ll[i] < ncol) {
  879. X        screen[i] = REALLOC(screen[i], int, ncol);
  880. X        for (j = ll[i]; j < ncol; j++)
  881. X        screen[i][j] = BLANK;
  882. X    }
  883. X    }
  884. X
  885. X    /* Check for screen consistency */
  886. X    for (i = 0; i < nlin; i++) {
  887. X    for (j = 0; j < ncol; j++) {
  888. X        switch (obj[screen[i][j]].type) {
  889. X        case FILLER:
  890. X        screen[i][j] = BLANK;
  891. X        break;
  892. X        case PLAYER:
  893. X        if (pfound)
  894. X            fatal("More than one start position in %s", path);
  895. X        pfound = 1;
  896. X        pline = i;
  897. X        pcol = j;
  898. X        break;
  899. X        case TELEPORT:
  900. X        if (teleport)
  901. X            fatal("More than one teleport in %s", path);
  902. X        teleport = 1;
  903. X        break;
  904. X        case ARRIVE:
  905. X        screen[i][j] = BLANK;
  906. X        if (tfound)
  907. X            fatal("More than one teleport point in %s", path);
  908. X        tfound = 1;
  909. X        tline = i;
  910. X        tcol = j;
  911. X        break;
  912. X        case MONSTER:
  913. X        nmonsters++;
  914. X        break;
  915. X        case BABY:
  916. X        fatal("Baby with no start direction in %s", path);
  917. X        break;
  918. X        case BABYNORTH:
  919. X        case BABYEAST:
  920. X        case BABYSOUTH:
  921. X        case BABYWEST:
  922. X        nmonsters++;
  923. X        nbaby++;
  924. X        break;
  925. X        case CAGE:
  926. X        ncage++;
  927. X        break;
  928. X        case TREASURE:
  929. X        ndiamonds++;
  930. X        break;
  931. X        case EXIT:
  932. X        nexit++;
  933. X        break;
  934. X        }
  935. X    }
  936. X    }
  937. X
  938. X    if (!pfound)
  939. X    fatal("No start position in %s", path);
  940. X    if (teleport && !tfound)
  941. X    fatal("No teleport point in %s", path);
  942. X    if (nexit > 1)
  943. X    fatal("More than one exit in %s", path);
  944. X    if (nexit == 0)
  945. X    fatal("No exit in %s", path);
  946. X
  947. X    /* Construct new position */
  948. X    p = newpos(screen, pline, pcol);
  949. X    p->nmoves = nmoves;
  950. X    p->diamonds = ndiamonds;
  951. X    p->monsters = nmonsters;
  952. X    p->diamonds += (nbaby < ncage ? nbaby : ncage);
  953. X
  954. X    /* Add monsters */
  955. X    for (i = 0; i < nlin; i++) {
  956. X    for (j = 0; j < ncol; j++) {
  957. X        switch (screen[i][j]) {
  958. X        case BABYNORTH:
  959. X        addmonster(p, BABY, i, j, NORTH, BLANK, 0);
  960. X        screen[i][j] = BABY;
  961. X        break;
  962. X        case BABYEAST:
  963. X        addmonster(p, BABY, i, j, EAST, BLANK, 0);
  964. X        screen[i][j] = BABY;
  965. X        break;
  966. X        case BABYSOUTH:
  967. X        addmonster(p, BABY, i, j, SOUTH, BLANK, 0);
  968. X        screen[i][j] = BABY;
  969. X        break;
  970. X        case BABYWEST:
  971. X        addmonster(p, BABY, i, j, WEST, BLANK, 0);
  972. X        screen[i][j] = BABY;
  973. X        break;
  974. X        case MONSTER:
  975. X        addmonster(p, MONSTER, i, j, NONE, BLANK, 0);
  976. X        break;
  977. X        }
  978. X    }
  979. X    }
  980. X
  981. X    nlines = nlin;
  982. X    ncols = ncol;
  983. X
  984. X    return p;
  985. }
  986. X
  987. /* Create and return a new position */
  988. struct pos *
  989. newpos(int **data, int pline, int pcol)
  990. {
  991. X    struct pos *new = ALLOC(struct pos, 1);
  992. X
  993. X    if (new == NULL) fatal("Out of memory");
  994. X    new->data = data;
  995. X    new->pline = pline;
  996. X    new->pcol = pcol;
  997. X    new->ml = NULL;
  998. X    new->score = 0;
  999. X    new->nmoves = 0;
  1000. X    new->diamonds = 0;
  1001. X    new->monsters = 0;
  1002. X    new->dead = 0;
  1003. X    new->dir = NONE;
  1004. X    new->prev = NULL;
  1005. X    new->next = NULL;
  1006. X
  1007. X    return new;
  1008. }
  1009. X
  1010. /* Copy and return a position */
  1011. struct pos *
  1012. copypos(struct pos *p)
  1013. {
  1014. X    struct pos *new = newpos(NULL, p->pline, p->pcol);
  1015. X    struct monster *m;
  1016. X    int **data = ALLOC(int *, nlines);
  1017. X    int i, j;
  1018. X
  1019. X    /* Copy screen */
  1020. X    for (i = 0; i < nlines; i++) {
  1021. X    data[i] = ALLOC(int, ncols);
  1022. X    for (j = 0; j < ncols; j++)
  1023. X        data[i][j] = p->data[i][j];
  1024. X    }
  1025. X    new->data = data;
  1026. X
  1027. X    /* Copy attributes */
  1028. X    new->score = p->score;
  1029. X    new->nmoves = p->nmoves;
  1030. X    new->dead = p->dead;
  1031. X    new->diamonds = p->diamonds;
  1032. X    new->monsters = p->monsters;
  1033. X    new->dir = p->dir;
  1034. X
  1035. X    /* Copy monsters */
  1036. X    for (m = p->ml; m != NULL; m = m->next) {
  1037. X    addmonster(new, m->type, m->line, m->col, m->heading,
  1038. X           m->under, m->dead);
  1039. X    }
  1040. X
  1041. X    return new;
  1042. }
  1043. X
  1044. /* Initialize positions */
  1045. void
  1046. initpos()
  1047. {
  1048. X    struct pos *p, *pnext;
  1049. X
  1050. X    for (p = firstpos; p != NULL; p = pnext) {
  1051. X    pnext = p->next;
  1052. X    destpos(p);
  1053. X    }
  1054. X
  1055. X    firstpos = lastpos = curpos;
  1056. }
  1057. X
  1058. /* Destroy a position */
  1059. void
  1060. destpos(struct pos *p)
  1061. {
  1062. X    int i;
  1063. X    struct monster *ml = p->ml, *mnext;
  1064. X
  1065. X    /* Kill monster list */
  1066. X    while (ml != NULL) {
  1067. X    mnext = ml->next;
  1068. X    DEALLOC(ml);
  1069. X    ml = mnext;
  1070. X    }
  1071. X
  1072. X    /* Kill screen data */
  1073. X    for (i = 0; i < nlines; i++) DEALLOC(p->data[i]);
  1074. X    DEALLOC(p->data);
  1075. X
  1076. X    /* Finally, kill position */
  1077. X    DEALLOC(p);
  1078. }
  1079. X
  1080. /* Add a position to the position stack */
  1081. void
  1082. addpos(struct pos *p)
  1083. {
  1084. X    lastpos->next = p;
  1085. X    p->prev = lastpos;
  1086. X    lastpos = p;
  1087. }
  1088. X
  1089. /* Remove all 'future' positions from the stack */
  1090. void
  1091. removepos()
  1092. {
  1093. X    struct pos *p;
  1094. X
  1095. X    while (lastpos != curpos) {
  1096. X    p = lastpos->prev;
  1097. X    destpos(lastpos);
  1098. X    lastpos = p;
  1099. X    }
  1100. }
  1101. X
  1102. /* Back up one position */
  1103. void
  1104. backpos()
  1105. {
  1106. X    if (curpos != firstpos) {
  1107. X    curpos = curpos->prev;
  1108. X    } else {
  1109. X    beep();
  1110. X    }
  1111. }
  1112. X
  1113. /* Move forward one position */
  1114. void
  1115. forwardpos()
  1116. {
  1117. X    if (curpos != lastpos) {
  1118. X    curpos = curpos->next;
  1119. X    } else {
  1120. X    beep();
  1121. X    }
  1122. }
  1123. X
  1124. /* Look up symbol type */
  1125. int
  1126. lookup(char sym)
  1127. {
  1128. X    int i;
  1129. X
  1130. X    for (i = 0; i < numobj; i++) {
  1131. X    if (obj[i].sym == sym) return i;
  1132. X    }
  1133. X
  1134. X    fatal("Unrecognized symbol: %c", sym);
  1135. X    return 0;            /* to shut lint up */
  1136. }
  1137. X
  1138. /* Return whether a position is on screen */
  1139. int
  1140. onscreen(int line, int col)
  1141. {
  1142. X    if (line < 0 || line >= nlines) return 0;
  1143. X    if (col < 0 || col >= ncols) return 0;
  1144. X
  1145. X    return 1;
  1146. }
  1147. X
  1148. /* Return a location value */
  1149. struct loc
  1150. curloc(struct pos *p, int line, int col)
  1151. {
  1152. X    struct loc l;
  1153. X
  1154. X    l.line = line;
  1155. X    l.col = col;
  1156. X    l.type = (onscreen(line, col) ? p->data[line][col] : ROCK1);
  1157. X
  1158. X    return l;
  1159. }
  1160. X
  1161. /* Return new location after a move */
  1162. struct loc
  1163. moveto(int line, int col, int dir)
  1164. {
  1165. X    return curloc(curpos, line+dirs[dir].line, col+dirs[dir].col);
  1166. }
  1167. SHAR_EOF
  1168.   $shar_touch -am 0616164094 'pos.c' &&
  1169.   chmod 0444 'pos.c' ||
  1170.   echo 'restore of pos.c failed'
  1171.   shar_count="`wc -c < 'pos.c'`"
  1172.   test 7220 -eq "$shar_count" ||
  1173.     echo "pos.c: original size 7220, current size $shar_count"
  1174. fi
  1175. # ============= mon.c ==============
  1176. if test -f 'mon.c' && test X"$1" != X"-c"; then
  1177.   echo 'x - skipping mon.c (File already exists)'
  1178. else
  1179.   echo 'x - extracting mon.c (text)'
  1180.   sed 's/^X//' << 'SHAR_EOF' > 'mon.c' &&
  1181. /*
  1182. X *  Wander version 1.0, Copyright (C) 1994 G. Hutchings
  1183. X *  Wander comes with ABSOLUTELY NO WARRANTY.
  1184. X *  This is free software, and you are welcome to redistribute it
  1185. X *  under certain conditions; see the file COPYING for details.
  1186. X */
  1187. X
  1188. /* Monster movement stuff */
  1189. X
  1190. #ifndef lint
  1191. static char rcsid[] = "$Id: mon.c,v 1.10 1994/06/16 14:16:44 glen Exp $";
  1192. #endif
  1193. X
  1194. #include <stdio.h>
  1195. #include "defs.h"
  1196. #include "data.h"
  1197. #include "proto.h"
  1198. #include "config.h"
  1199. X
  1200. /* Add a monster to a position */
  1201. void
  1202. addmonster(struct pos *p, int type, int line, int col,
  1203. X       int heading, int under, int dead)
  1204. {
  1205. X    struct monster *new = newmonster(line, col, heading);
  1206. X
  1207. X    new->type = type;
  1208. X    new->under = under;
  1209. X    new->dead = dead;
  1210. X    new->next = p->ml;
  1211. X    p->ml = new;
  1212. }
  1213. X
  1214. /* Return a newly allocated monster */
  1215. struct monster *
  1216. newmonster(int line, int col, int heading)
  1217. {
  1218. X    struct monster *new = ALLOC(struct monster, 1);
  1219. X
  1220. X    if (new == NULL)
  1221. X    fatal("Out of memory");
  1222. X
  1223. X    new->line = line;
  1224. X    new->col = col;
  1225. X    new->heading = heading;
  1226. X    new->under = BLANK;
  1227. X    new->dead = 0;
  1228. X    new->next = NULL;
  1229. X
  1230. X    return new;
  1231. }
  1232. X
  1233. /* Move the monsters */
  1234. void
  1235. movemonsters()
  1236. {
  1237. X    struct monster *m, *found;
  1238. X    struct loc l;
  1239. X    int line, col, type, lnew, cnew, i, dist, d, dir;
  1240. X
  1241. X    /* Don't bother if you're dead */
  1242. X    if (curpos->dead) return;
  1243. X
  1244. X    for (m = curpos->ml; m != NULL; m = m->next) {
  1245. X    /* Skip if dead */
  1246. X    if (m->dead) continue;
  1247. X
  1248. X    line = m->line;
  1249. X    col = m->col;
  1250. X    type = curpos->data[line][col];
  1251. X    lnew = line;
  1252. X    cnew = col;
  1253. X
  1254. X    switch (type) {
  1255. X    case MONSTER:
  1256. X        /* Heads straight for you */
  1257. X        dist = range(line, col, curpos->pline, curpos->pcol);
  1258. X
  1259. X        for (dir = 0; dir < numdir; dir++) {
  1260. X        l = moveto(line, col, dir);
  1261. X        if (l.type == BLANK ||
  1262. X            l.type == PLAYER) {
  1263. X            d = range(l.line, l.col, curpos->pline, curpos->pcol);
  1264. X            if (d > dist) continue;
  1265. X            lnew = l.line;
  1266. X            cnew = l.col;
  1267. X            dist = d;
  1268. X        }
  1269. X        }
  1270. X
  1271. X        break;
  1272. X    case BABY:
  1273. X        /* Follows left-hand rule */
  1274. X        m->heading = (m->heading+numdir-1) % numdir;
  1275. X
  1276. X        /* Try to turn */
  1277. X        for (i = 0; i < numdir; i++) {
  1278. X        l = moveto(line, col, m->heading);
  1279. X        if (l.type == BLANK ||
  1280. X            l.type == EARTH || /* pass straight through earth */
  1281. X            l.type == CAGE || /* can enter cages */
  1282. X            l.type == BABY || /* ignore each other */
  1283. X            l.type == PLAYER) {    /* yum! */
  1284. X            lnew = l.line;
  1285. X            cnew = l.col;
  1286. X            break;
  1287. X        }
  1288. X
  1289. X        m->heading = (m->heading+1) % numdir;
  1290. X        }
  1291. X
  1292. X        break;
  1293. X    default:
  1294. X        fatal("Monster movement error");
  1295. X    }
  1296. X
  1297. X    /* Remove monster from screen temporarily */
  1298. X    m->line = m->col = -1;
  1299. X
  1300. X    /* Replace contents of old position */
  1301. X    if ((found = findmonster(line, col)) != NULL)
  1302. X        curpos->data[line][col] = found->type;
  1303. X    else
  1304. X        curpos->data[line][col] = m->under;
  1305. X
  1306. X    /* Update what monster is now on top of */
  1307. X    if ((found = findmonster(lnew, cnew)) != NULL)
  1308. X        m->under = found->under;
  1309. X    else
  1310. X        m->under = curpos->data[lnew][cnew];
  1311. X
  1312. X    /* Move monster to new position */
  1313. X    curpos->data[lnew][cnew] = type;
  1314. X    m->line = lnew;
  1315. X    m->col = cnew;
  1316. X
  1317. X    /* Check for moving objects */
  1318. X    vacate(line, col);
  1319. X    moveinto(lnew, cnew);
  1320. X
  1321. X    /* Check for monster munch */
  1322. X    if (lnew == curpos->pline && cnew == curpos->pcol) {
  1323. X        doeffect(lnew, cnew, EATEN);
  1324. X        die("You've been eaten by a hungry monster!");
  1325. X    }
  1326. X
  1327. X    /* Check for caged baby monster */
  1328. X    if (type == BABY && m->under == CAGE) {
  1329. X        m->under = TREASURE;
  1330. X        doeffect(lnew, cnew, CAUGHT);
  1331. X        killmonster(lnew, cnew);
  1332. X    }
  1333. X    }
  1334. }
  1335. X
  1336. /* Kill a monster */
  1337. void
  1338. killmonster(int line, int col)
  1339. {
  1340. X    struct monster *m;
  1341. X    int type = curpos->data[line][col];
  1342. X
  1343. X    for (m = curpos->ml; m != NULL; m = m->next) {
  1344. X    if (m->line == line && m->col == col) {
  1345. X        curpos->data[line][col] = m->under;
  1346. X        curpos->score += obj[type].score;
  1347. X        curpos->monsters--;
  1348. X        m->dead = 1;
  1349. X    }
  1350. X    }
  1351. }
  1352. X
  1353. /* Return first monster found at specified location */
  1354. struct monster *
  1355. findmonster(int line, int col)
  1356. {
  1357. X    struct monster *m;
  1358. X
  1359. X    for (m = curpos->ml; m != NULL; m = m->next) {
  1360. X    if (m->line == line && m->col == col && !m->dead) return m;
  1361. X    }
  1362. X
  1363. X    return NULL;
  1364. }
  1365. X
  1366. /* Return the range twixt two squares */
  1367. int
  1368. range(int l1, int c1, int l2, int c2)
  1369. {
  1370. X    int ldif = l1-l2;
  1371. X    int cdif = c1-c2;
  1372. X
  1373. X    return ldif*ldif+cdif*cdif;
  1374. }
  1375. SHAR_EOF
  1376.   $shar_touch -am 0616151894 'mon.c' &&
  1377.   chmod 0444 'mon.c' ||
  1378.   echo 'restore of mon.c failed'
  1379.   shar_count="`wc -c < 'mon.c'`"
  1380.   test 4266 -eq "$shar_count" ||
  1381.     echo "mon.c: original size 4266, current size $shar_count"
  1382. fi
  1383. # ============= draw.c ==============
  1384. if test -f 'draw.c' && test X"$1" != X"-c"; then
  1385.   echo 'x - skipping draw.c (File already exists)'
  1386. else
  1387.   echo 'x - extracting draw.c (text)'
  1388.   sed 's/^X//' << 'SHAR_EOF' > 'draw.c' &&
  1389. /*
  1390. X *  Wander version 1.0, Copyright (C) 1994 G. Hutchings
  1391. X *  Wander comes with ABSOLUTELY NO WARRANTY.
  1392. X *  This is free software, and you are welcome to redistribute it
  1393. X *  under certain conditions; see the file COPYING for details.
  1394. X */
  1395. X
  1396. /* Screen drawing functions */
  1397. X
  1398. #ifndef lint
  1399. static char rcsid[] = "$Id: draw.c,v 1.32 1994/06/23 14:56:12 glen Exp $";
  1400. #endif
  1401. X
  1402. #if defined(BSDCURSES) || defined(SYSVR3)
  1403. #include <curses.h>
  1404. #else
  1405. #include <cursesX.h>
  1406. #endif
  1407. X
  1408. #include <stdarg.h>
  1409. #include <signal.h>
  1410. #include <ctype.h>
  1411. #include "defs.h"
  1412. #include "data.h"
  1413. #include "effect.h"
  1414. #include "proto.h"
  1415. #include "config.h"
  1416. X
  1417. /* Screen display strings */
  1418. #define TITLE            " W A N D E R "
  1419. #define WIZSTRING        "Wizard"
  1420. #define DONESTRING        "Old level"
  1421. #define TESTSTRING        "Testing level"
  1422. #define ALERTSTRING        "Monster alert!"
  1423. X
  1424. /* File for panic saves */
  1425. #define PANICFILE        "WANDERBUG"
  1426. X
  1427. /* Border characters */
  1428. #define VLINE        '|'
  1429. #define HLINE        '-'
  1430. #define ULCORNER    '+'
  1431. #define URCORNER    '+'
  1432. #define LLCORNER    '+'
  1433. #define LRCORNER    '+'
  1434. X
  1435. /* Special mini-display characters */
  1436. #define BLOCK        '#'
  1437. #define ALEFT        '<'
  1438. #define ARIGHT        '>'
  1439. #define DIAMOND        '*'
  1440. X
  1441. /* Extended characters (if available) */
  1442. #ifndef XCHARS
  1443. #define X_VLINE        VLINE
  1444. #define X_HLINE        HLINE
  1445. #define X_ULCORNER    ULCORNER
  1446. #define X_URCORNER    URCORNER
  1447. #define X_LLCORNER    LLCORNER
  1448. #define X_LRCORNER    LRCORNER
  1449. #define X_BLOCK        BLOCK
  1450. #define X_ALEFT        ALEFT
  1451. #define X_ARIGHT    ARIGHT
  1452. #define X_DIAMOND    DIAMOND
  1453. #else
  1454. #define X_VLINE        ACS_VLINE
  1455. #define X_HLINE        ACS_HLINE
  1456. #define X_ULCORNER    ACS_ULCORNER
  1457. #define X_URCORNER    ACS_URCORNER
  1458. #define X_LLCORNER    ACS_LLCORNER
  1459. #define X_LRCORNER    ACS_LRCORNER
  1460. #define X_BLOCK        ACS_CKBOARD
  1461. #define X_ALEFT        ACS_LARROW
  1462. #define X_ARIGHT    ACS_RARROW
  1463. #define X_DIAMOND    ACS_DIAMOND
  1464. #endif
  1465. X
  1466. char msgtext[BUFSIZ];        /* Message text */
  1467. int showmessage = 0;        /* Whether to display it */
  1468. X
  1469. /* Set up screen */
  1470. void
  1471. initscreen()
  1472. {
  1473. X    if (!screeninit) {
  1474. #ifdef BSDCURSES
  1475. X    if (initscr() == ERR)
  1476. X        fatal("Can't initialize terminal");
  1477. #else
  1478. X    if (initscr() == NULL)
  1479. X        fatal("Can't initialize terminal");
  1480. X    fixterm();
  1481. X    intrflush(stdscr, FALSE);
  1482. #endif
  1483. X    signal(SIGINT, quit);
  1484. #ifdef BSD42
  1485. X    signal(SIGSEGV, panic);
  1486. X    signal(SIGBUS, panic);
  1487. X    signal(SIGILL, panic);
  1488. X    signal(SIGFPE, panic);
  1489. #endif
  1490. X    nonl();
  1491. X    noecho();
  1492. X    cbreak();
  1493. X
  1494. X    screeninit = 1;
  1495. X    }
  1496. }
  1497. X
  1498. /* Finish with screen */
  1499. void
  1500. endscreen()
  1501. {
  1502. X    if (screeninit) {
  1503. X    mvcur(0, COLS-1, LINES-1, 0);
  1504. #ifdef BSDCURSES
  1505. X    nocbreak();
  1506. X    echo();
  1507. X    nl();
  1508. #else
  1509. X    resetterm();
  1510. #endif
  1511. X    endwin();
  1512. X    screeninit = 0;
  1513. X    }
  1514. }
  1515. X
  1516. /* Draw a position */
  1517. void
  1518. drawpos(struct pos *p)
  1519. {
  1520. X    int startline, startcol, line, col, i, j, sym;
  1521. X    struct monster *m;
  1522. X    struct loc l;
  1523. X    char buf[BUFSIZ], str[BUFSIZ];
  1524. X
  1525. X    /* Do nothing if not updating picture */
  1526. X    if (!redrawscreen) return;
  1527. X
  1528. X    /* Wipe old picture */
  1529. X    erase();
  1530. X
  1531. X    /* Draw title */
  1532. X    move(0, (COLS+1-strlen(TITLE))/2);
  1533. X    setbold(1);
  1534. X    standout();
  1535. X    addstr(TITLE);
  1536. X    standend();
  1537. X    setbold(0);
  1538. X
  1539. X    if (wizard && !testlevel) {
  1540. X    move(0, (COLS-strlen(WIZSTRING)));
  1541. X    standout();
  1542. X    addstr(WIZSTRING);
  1543. X    standend();
  1544. X    } else if (wizard && testlevel) {
  1545. X    move(0, (COLS-strlen(TESTSTRING)));
  1546. X    standout();
  1547. X    addstr(TESTSTRING);
  1548. X    standend();
  1549. X    } else if (donelevel) {
  1550. X    move(0, (COLS-strlen(DONESTRING)));
  1551. X    standout();
  1552. X    addstr(DONESTRING);
  1553. X    standend();
  1554. X    }
  1555. X
  1556. X    /* Draw stats */
  1557. X    if (!testlevel)
  1558. X    sprintf(buf, "Level: %d", level);
  1559. X    else
  1560. X    strcpy(buf, "");
  1561. X
  1562. X    sprintf(str, "   Score: %d   Diamonds: %d",
  1563. X        curpos->score, curpos->diamonds);
  1564. X    strcat(buf, str);
  1565. X
  1566. X    if (curpos->nmoves >= 0) {
  1567. X    sprintf(str, "   Moves left: %d", curpos->nmoves);
  1568. X    strcat(buf, str);
  1569. X    }
  1570. X
  1571. X    move(2, (COLS+1-strlen(buf))/2);
  1572. X    addstr(buf);
  1573. X
  1574. X    /* Draw monster alert if required */
  1575. X    if (curpos->monsters > 0) {
  1576. X    move(0, 0);
  1577. X    standout();
  1578. X    addstr(ALERTSTRING);
  1579. X    standend();
  1580. X    }
  1581. X
  1582. X    /* Display message if required */
  1583. X    if (showmessage) {
  1584. X    move(LINES-1, 0);
  1585. X    clrtoeol();
  1586. X    move(LINES-1, (COLS+1-strlen(msgtext))/2);
  1587. X    addstr(msgtext);
  1588. X    showmessage = 0;
  1589. X    }
  1590. X
  1591. X    /* Draw the screen piccie */
  1592. X    if (minidisplay) {
  1593. X    startline = (LINES-nlines)/2;
  1594. X    if (startline < 4) startline = 4;
  1595. X    startcol = (COLS-ncols)/2;
  1596. X    screenborder(startline, startcol, nlines, ncols);
  1597. X
  1598. X    for (i = 0; i < nlines; i++) {
  1599. X        line = i+startline;
  1600. X        for (j = 0; j < ncols; j++) {
  1601. X        col = j+startcol;
  1602. X
  1603. X        l = curloc(p, i, j);
  1604. X        switch (l.type) {
  1605. X        case PLAYER:
  1606. X            /* Don't draw player if they're dead or */
  1607. X            /* they've left the level */
  1608. X            if (exited || p->dead) l.type = BLANK;
  1609. X            break;
  1610. X        case MONSTER:
  1611. X        case BABY:
  1612. X            /* Can only see monsters here if wizard */
  1613. X            if (!wizard) {
  1614. X            m = findmonster(i, j);
  1615. X            if (m == NULL)
  1616. X                fatal("monster movement error");
  1617. X            else
  1618. X                l.type = m->under;
  1619. X            }
  1620. X            break;
  1621. X        }
  1622. X
  1623. X        /* Check for extended character if required */
  1624. X        sym = obj[l.type].sym;
  1625. X        if (xchars) sym = extendchar(sym);
  1626. X
  1627. X        if (obj[l.type].bold) setbold(1);
  1628. X        mvaddch(line, col, sym);
  1629. X        if (obj[l.type].bold) setbold(0);
  1630. X        }
  1631. X    }
  1632. X
  1633. X    if (p->dead || exited)
  1634. X        move(LINES-1, 0);
  1635. X    else
  1636. X        move(p->pline+startline, p->pcol+startcol);
  1637. X    } else {
  1638. X    startline = (LINES-(WINLINES*2))/2;
  1639. X    if (startline < 4) startline = 4;
  1640. X    startcol = (COLS-(WINCOLS*3))/2;
  1641. X    screenborder(startline, startcol, WINLINES*2, WINCOLS*3);
  1642. X
  1643. X    for (i = wline; i < wline+WINLINES; i++) {
  1644. X        line = 2*(i-wline)+startline;
  1645. X        for (j = wcol; j < wcol+WINCOLS; j++) {
  1646. X        col = 3*(j-wcol)+startcol;
  1647. X        l = curloc(p, i, j);
  1648. X
  1649. X        /* Don't draw player if they're dead or they've */
  1650. X        /* left the level */
  1651. X        if (l.type == PLAYER)
  1652. X            if (exited || p->dead) l.type = BLANK;
  1653. X
  1654. X        if (obj[l.type].bold) setbold(1);
  1655. X        mvaddstr(line  , col, obj[l.type].bigsym[0]);
  1656. X        mvaddstr(line+1, col, obj[l.type].bigsym[1]);
  1657. X        if (obj[l.type].bold) setbold(0);
  1658. X        }
  1659. X    }
  1660. X
  1661. X    move(LINES-1, 0);
  1662. X    }
  1663. X
  1664. X    refresh();
  1665. }
  1666. X
  1667. /* Draw a border around screen */
  1668. void
  1669. screenborder(int slin, int scol, int nlin, int ncol)
  1670. {
  1671. X    int i;
  1672. X
  1673. X    /* Left/right */
  1674. X    for (i = slin-1; i <= slin+nlin; i++) {
  1675. X    mvaddch(i, scol-1   , (xchars ? X_VLINE : VLINE));
  1676. X    mvaddch(i, scol+ncol, (xchars ? X_VLINE : VLINE));
  1677. X    }
  1678. X
  1679. X    /* Top/bottom */
  1680. X    for (i = scol-1; i <= scol+ncol; i++) {
  1681. X    mvaddch(slin-1   , i, (xchars ? X_HLINE : HLINE));
  1682. X    mvaddch(slin+nlin, i, (xchars ? X_HLINE : HLINE));
  1683. X    }
  1684. X
  1685. X    /* Corners */
  1686. X    mvaddch(slin-1   , scol-1,    (xchars ? X_ULCORNER : ULCORNER));
  1687. X    mvaddch(slin-1   , scol+ncol, (xchars ? X_URCORNER : URCORNER));
  1688. X    mvaddch(slin+nlin, scol-1   , (xchars ? X_LLCORNER : LLCORNER));
  1689. X    mvaddch(slin+nlin, scol+ncol, (xchars ? X_LRCORNER : LRCORNER));
  1690. }
  1691. X
  1692. /* Do a special effect sequence */
  1693. void
  1694. doeffect(int i, int j, int num)
  1695. {
  1696. X    int startline, startcol, line, col, len;
  1697. X    int nlin = 0, ncol = 0, effnum, k;
  1698. X    char ***seq, c;
  1699. X    WINDOW *w;
  1700. X
  1701. X    /* No effects in minidisplay mode */
  1702. X    if (minidisplay) return;
  1703. X
  1704. X    /* Look up effect */
  1705. X    for (effnum = 0; effnum < numeff; effnum++) {
  1706. X    if (effs[effnum].type == num) break;
  1707. X    }
  1708. X    if (effnum == numeff) return;
  1709. X
  1710. X    /* Find where to draw it */
  1711. X    if (minidisplay) {
  1712. X    startline = (LINES-nlines)/2;
  1713. X    if (startline < 4) startline = 4;
  1714. X    startcol = (COLS-ncols)/2;
  1715. X    line = startline+i;
  1716. X    col = startcol+j;
  1717. X    } else {
  1718. X    if (i < wline || i >= wline+WINLINES) return;
  1719. X    if (j < wcol || j >= wcol+WINCOLS) return;
  1720. X    startline = (LINES-(WINLINES*2))/2;
  1721. X    if (startline < 4) startline = 4;
  1722. X    startcol = (COLS-(WINCOLS*3))/2;
  1723. X    line = 2*(i-wline)+startline;
  1724. X    col = 3*(j-wcol)+startcol+1;
  1725. X    }
  1726. X
  1727. X    /* Find dimensions of sequence */
  1728. X    seq = effs[effnum].seq;
  1729. X    for (i = 0; seq[i] != NULL; i++) {
  1730. X    for (j = 0; seq[i][j] != NULL; j++)
  1731. X        if ((len = strlen(seq[i][j])) > ncol) ncol = len;
  1732. X    if (j > nlin) nlin = j;
  1733. X    }
  1734. X
  1735. X    /* Set up window to display it */
  1736. X    line -= nlin/2-1;
  1737. X    col -= ncol/2;
  1738. X    w = newwin(nlin+1, ncol+1, line, col);
  1739. X
  1740. X    /* Make sure screen is up to date */
  1741. X    drawpos(curpos);
  1742. X
  1743. X    /* Pause before first frame if required */
  1744. X    if (effs[effnum].startdelay > 0) {
  1745. X    move(0, 0);
  1746. X    refresh();
  1747. X    freeze(effs[effnum].startdelay);
  1748. X    }
  1749. X
  1750. X    /* Draw frames */
  1751. X    for (k = 0; seq[k] != NULL; k++) {
  1752. X    for (i = 0; i <= nlin; i++) {
  1753. X        for (j = 0; j <= ncol; j++) {
  1754. X        move(line+i, col+j);
  1755. X        mvwaddch(w, i, j, inch());
  1756. X        }
  1757. X    }
  1758. X
  1759. X    for (i = 0; seq[k][i] != NULL; i++) {
  1760. X        for (j = 0; (c = seq[k][i][j]) != '\0'; j++) {
  1761. X        switch (c) {
  1762. X        case ' ':
  1763. X            break;
  1764. X        case '?':
  1765. X            c = ' ';
  1766. X            /* FALLTHROUGH */
  1767. X        default:
  1768. X            mvwaddch(w, i, j, c);
  1769. X        }
  1770. X        }
  1771. X    }
  1772. X
  1773. X    wrefresh(w);
  1774. X
  1775. X    /* Pause between frames if required */
  1776. X    if (effs[effnum].delay > 0) {
  1777. X        move(0, 0);
  1778. X        refresh();
  1779. X        freeze(effs[effnum].delay);
  1780. X    }
  1781. X    }
  1782. X
  1783. X    /* Pause on last frame if required */
  1784. X    if (effs[effnum].enddelay > 0) {
  1785. X    move(0, 0);
  1786. X    refresh();
  1787. X    freeze(effs[effnum].enddelay);
  1788. X    }
  1789. X
  1790. X    /* Delete effects window */
  1791. X    delwin(w);
  1792. }
  1793. X
  1794. /* Return an extended character */
  1795. int
  1796. extendchar(int c)
  1797. {
  1798. X    if (xchars) {
  1799. X    switch (c) {
  1800. X    case BLOCK:
  1801. X        return X_BLOCK;
  1802. X    case ALEFT:
  1803. X        return X_ALEFT;
  1804. X    case ARIGHT:
  1805. X        return X_ARIGHT;
  1806. X    case DIAMOND:
  1807. X        return X_DIAMOND;
  1808. X    }
  1809. X    }
  1810. X
  1811. X    return c;
  1812. }
  1813. X
  1814. /* Recentre you on the screen */
  1815. void
  1816. recentre()
  1817. {
  1818. X    wline = curpos->pline-(WINLINES/2);
  1819. X    wcol = curpos->pcol-(WINCOLS/2);
  1820. X
  1821. X    wallscroll();
  1822. }
  1823. X
  1824. /* Scroll window if required */
  1825. void
  1826. scroll()
  1827. {
  1828. X    int lines = WINLINES-(2*bordersize);
  1829. X    int cols = WINCOLS-(2*bordersize);
  1830. X
  1831. X    if (lines > 0 && cols > 0 && bordersize > 0) {
  1832. X    while (curpos->pline-wline < bordersize) wline -= lines;
  1833. X    while (curpos->pline-wline > WINLINES-1-bordersize) wline += lines;
  1834. X    while (curpos->pcol-wcol < bordersize) wcol -= cols;
  1835. X    while (curpos->pcol-wcol > WINCOLS-1-bordersize) wcol += cols;
  1836. X
  1837. X    wallscroll();
  1838. X    } else {
  1839. X    recentre();
  1840. X    }
  1841. }
  1842. X
  1843. /* Scroll so that outer walls only show at most one thickness */
  1844. void
  1845. wallscroll()
  1846. {
  1847. X    while (wline < -1) wline++;
  1848. X    while (wline+WINLINES > nlines+1) wline--;
  1849. X    while (wcol < -1) wcol++;
  1850. X    while (wcol+WINCOLS > ncols+1) wcol--;
  1851. }
  1852. X
  1853. /* Redraw screen */
  1854. void
  1855. redraw()
  1856. {
  1857. X    clearok(curscr, TRUE);
  1858. X    wrefresh(curscr);
  1859. }
  1860. X
  1861. /* Set/unset bold display */
  1862. void
  1863. setbold(int flag)
  1864. {
  1865. #ifdef BSDCURSES
  1866. X    /* No-op */
  1867. #else
  1868. X    attrset(flag ? A_BOLD : 0);
  1869. #endif
  1870. }
  1871. X
  1872. /* Return a typed-in string */
  1873. char *
  1874. getstring(char *msg)
  1875. {
  1876. X    static char buf[BUFSIZ];
  1877. X    int col = (COLS+1-strlen(msg))/2;
  1878. X    int pcol = col+strlen(msg);
  1879. X    int i = 0, key;
  1880. X
  1881. X    move(LINES-1, 0);
  1882. X    clrtoeol();
  1883. X    move(LINES-1, col);
  1884. X    addstr(msg);
  1885. X    move(LINES-1, pcol);
  1886. X
  1887. X    while (1) {
  1888. X    refresh();
  1889. X    key = keypress();
  1890. X
  1891. X    switch (key) {
  1892. X    case 10:        /* RET - send string */
  1893. X        move(LINES-1, 0);
  1894. X        clrtoeol();
  1895. X        refresh();
  1896. X        buf[i] = '\0';
  1897. X        return (strlen(buf) > 0 ? buf : NULL);
  1898. X    case 21:        /* Ctrl-U - kill line */
  1899. X        while (i > 0) {
  1900. X        i--;
  1901. X        move(LINES-1, pcol+i);
  1902. X        delch();
  1903. X        }
  1904. X        break;
  1905. X    case 127:        /* DEL - backup one */
  1906. X        if (i > 0) {
  1907. X        i--;
  1908. X        move(LINES-1, pcol+i);
  1909. X        delch();
  1910. X        }
  1911. X        break;
  1912. X    default:        /* if printable, print it */
  1913. X        if (isprint(key)) {
  1914. X        addch(key);
  1915. X        buf[i++] = key;
  1916. X        }
  1917. X    }
  1918. X    }
  1919. X
  1920. X    /* NOTREACHED */
  1921. }
  1922. X
  1923. /* Return answer to a yes/no question */
  1924. int
  1925. query(char *msg, int def)
  1926. {
  1927. X    int reply, c, col = (COLS+1-strlen(msg))/2;
  1928. X
  1929. X    move(LINES-1, 0);
  1930. X    clrtoeol();
  1931. X    move(LINES-1, col);
  1932. X    addstr(msg);
  1933. X
  1934. X    move(LINES-1, col+strlen(msg));
  1935. X    refresh();
  1936. X
  1937. X    c = keypress();
  1938. X    switch (c) {
  1939. X    case 'y':
  1940. X    case 'Y':
  1941. X    reply = 1;
  1942. X    break;
  1943. X    case 'n':
  1944. X    case 'N':
  1945. X    reply = 0;
  1946. X    break;
  1947. X    default:
  1948. X    reply = def;
  1949. X    break;
  1950. X    }
  1951. X
  1952. X    move(LINES-1, 0);
  1953. X    clrtoeol();
  1954. X    refresh();
  1955. X
  1956. X    return reply;
  1957. }
  1958. X
  1959. /* Write a message at bottom of screen */
  1960. void
  1961. message(char *fmt, ...)
  1962. {
  1963. X    va_list args;
  1964. X
  1965. X    va_start(args, fmt);
  1966. X    vsprintf(msgtext, fmt, args);
  1967. X    va_end(args);
  1968. X
  1969. X    showmessage = 1;
  1970. }
  1971. X
  1972. /* Catch a quit signal */
  1973. void
  1974. quit()
  1975. {
  1976. #ifdef XCURSES
  1977. X    flushinp();
  1978. #endif
  1979. X
  1980. X    /* Can't get SYSV signals to work properly yet.  When I get */
  1981. X    /* around to it... */
  1982. #ifdef SYSVR3
  1983. X    endscreen();
  1984. X    exit(0);
  1985. #else
  1986. X    signal(SIGINT, SIG_IGN);
  1987. X    if (query("Really *quit*? ", 0)) {
  1988. X    endscreen();
  1989. X    exit(0);
  1990. X    } else {
  1991. X    signal(SIGINT, quit);
  1992. X    drawpos(curpos);
  1993. X    }
  1994. #endif
  1995. }
  1996. X
  1997. /* Catch a program fault */
  1998. void
  1999. panic()
  2000. {
  2001. X    FILE *fp = fopen(PANICFILE, "w");
  2002. X
  2003. X    endscreen();
  2004. X
  2005. X    /* Try to save the moves that led up to it in a file */
  2006. X    printf("PANIC!!!  Major program failure!\n");
  2007. X    if (fp != NULL) {
  2008. X    writemoves(fp);
  2009. X    fclose(fp);
  2010. X    printf("Moves saved to file %s\n", PANICFILE);
  2011. X    printf("Now get %s to sort out the problem.\n", WIZARD);
  2012. X    } else {
  2013. X    printf("Typical!  I can't even open the panic save file.\n");
  2014. X    printf("I give up!\n");
  2015. X    }
  2016. X
  2017. X    exit(1);
  2018. }
  2019. X
  2020. #ifdef BSDCURSES
  2021. /* Ring the bell */
  2022. void
  2023. beep()
  2024. {
  2025. X    putchar('');
  2026. }
  2027. #endif
  2028. SHAR_EOF
  2029.   $shar_touch -am 0623155894 'draw.c' &&
  2030.   chmod 0444 'draw.c' ||
  2031.   echo 'restore of draw.c failed'
  2032.   shar_count="`wc -c < 'draw.c'`"
  2033.   test 12690 -eq "$shar_count" ||
  2034.     echo "draw.c: original size 12690, current size $shar_count"
  2035. fi
  2036. : || echo 'restore of move.c failed'
  2037. echo 'End of part 1, continue with part 2'
  2038. exit 0
  2039.  
  2040. -- 
  2041.