home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume9 / umoria3 / part20 < prev    next >
Encoding:
Internet Message Format  |  1990-05-21  |  60.1 KB

  1. Path: uunet!ogicse!zephyr.ens.tek.com!tekred!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v09i075:  umoria3 - single player dungeon simulation (ver. 5.2), Part20/31
  5. Message-ID: <5610@tekred.CNA.TEK.COM>
  6. Date: 17 May 90 16:24:43 GMT
  7. Sender: news@tekred.CNA.TEK.COM
  8. Lines: 2796
  9. Approved: billr@saab.CNA.TEK.COM
  10. Posted: Thu May 17 09:24:43 1990
  11.  
  12. Submitted-by: wilson@ernie.Berkeley.EDU (Jim Wilson)
  13. Posting-number: Volume 9, Issue 75
  14. Archive-name: umoria3/Part20
  15. Supersedes: umoria2: Volume 5, Issue 32-37,41-52,87
  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 20 (of 31)."
  26. # Contents:  source/io.c util/mc/creature.y
  27. # Wrapped by billr@saab on Wed May 16 11:54:35 1990
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. if test -f 'source/io.c' -a "${1}" != "-c" ; then 
  30.   echo shar: Will not clobber existing file \"'source/io.c'\"
  31. else
  32. echo shar: Extracting \"'source/io.c'\" \(29702 characters\)
  33. sed "s/^X//" >'source/io.c' <<'END_OF_FILE'
  34. X/* io.c: terminal I/O code, uses the curses package
  35. X
  36. X   Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
  37. X
  38. X   This software may be copied and distributed for educational, research, and
  39. X   not for profit purposes provided that this copyright and statement are
  40. X   included in all such copies. */
  41. X
  42. X#ifdef MSDOS
  43. X#include <stdio.h>
  44. X#include <process.h>
  45. X#endif
  46. X
  47. X#if defined(NLS) && defined(lint)
  48. X/* for AIX, don't let curses include the NL stuff */
  49. X#undef NLS
  50. X#endif
  51. X
  52. X#if !defined(GEMDOS)
  53. X#ifdef MAC
  54. X#include <scrnmgr.h>
  55. X#else
  56. X#include <curses.h>
  57. X#endif
  58. X#else
  59. X#define ATARIST_MWC
  60. X#include "curses.h"
  61. Xlong wgetch();
  62. X#include <osbind.h>
  63. Xchar *getenv();
  64. X#endif
  65. X
  66. X#include "constant.h"
  67. X#include "config.h"
  68. X#include "types.h"
  69. X#include "externs.h"
  70. X
  71. X#include <ctype.h>
  72. X
  73. X#if defined(SYS_V) && defined(lint)
  74. X/* for AIX, prevent hundreds of unnecessary lint errors, must define before
  75. X   signal.h is included */
  76. X#define _h_IEEETRAP
  77. Xtypedef struct { int stuff; } fpvmach;
  78. X#endif
  79. X
  80. X#if defined(MSDOS)
  81. X#if defined(ANSI)
  82. X#include "ms_ansi.h"
  83. X#endif
  84. X#else /* not msdos */
  85. X#if !defined(ATARIST_MWC) && !defined(MAC)
  86. X#ifndef VMS
  87. X#include <sys/ioctl.h>
  88. X#endif
  89. X#include <signal.h>
  90. X#endif
  91. X#endif
  92. X
  93. X#ifndef USG
  94. X/* only needed for Berkeley UNIX */
  95. X#include <sys/param.h>
  96. X#include <sys/file.h>
  97. X#include <sys/types.h>
  98. X#endif
  99. X
  100. X#ifdef USG
  101. X#ifndef ATARIST_MWC
  102. X#include <string.h>
  103. X#else
  104. X#include "string.h"
  105. X#endif
  106. X#if !defined(MAC) && !defined(MSDOS) && !defined(ATARIST_MWC)
  107. X#include <termio.h>
  108. X#endif
  109. X#else
  110. X#ifndef VMS
  111. X#include <strings.h>
  112. X#if defined(atarist) && defined(__GNUC__)
  113. X/* doesn't have sys/wait.h */
  114. X#else
  115. X#include <sys/wait.h>
  116. X#endif
  117. X#endif
  118. X#endif
  119. X
  120. X#if defined(SYS_V) && defined(lint)
  121. Xstruct screen { int dumb; };
  122. X#endif
  123. X
  124. X/* Fooling lint. Unfortunately, c defines all the TIO.      -CJS-
  125. X   constants to be long, and lint expects them to be int. Also,
  126. X   ioctl is sometimes called with just two arguments. The
  127. X   following definition keeps lint happy. It may need to be
  128. X   reset for different systems.     */
  129. X#ifndef MAC
  130. X#ifdef lint
  131. X#ifdef Pyramid
  132. X/* Pyramid makes constants greater than 65535 into long! Gakk! -CJS- */
  133. X/*ARGSUSED*/
  134. X/*VARARGS2*/
  135. Xstatic Ioctl(i, l, p) long l; char *p; { return 0; }
  136. X#else
  137. X/*ARGSUSED*/
  138. X/*VARARGS2*/
  139. Xstatic Ioctl(i, l, p) char *p; { return 0; }
  140. X#endif
  141. X#define ioctl        Ioctl
  142. X#endif
  143. X
  144. X#if !defined(USG) && defined(lint)
  145. X/* This use_value hack is for curses macros which return a value,
  146. X   but don't shut up about it when you try to tell them (void).     */
  147. X/* only needed for Berkeley UNIX */
  148. Xint Use_value;
  149. X#define use_value   Use_value +=
  150. X#else
  151. X#define use_value
  152. X#endif
  153. X
  154. X#if defined(SYS_V) && defined(lint)
  155. X/* This use_value2 hack is for curses macros which use a conditional
  156. X   expression, and which say null effect even if you cast to (void). */
  157. X/* only needed for SYS V */
  158. Xint Use_value2;
  159. X#define use_value2  Use_value2 +=
  160. X#else
  161. X#define use_value2
  162. X#endif
  163. X
  164. X#endif
  165. X
  166. X#ifndef MAC
  167. Xchar *getenv();
  168. X#endif
  169. X
  170. X#ifdef USG
  171. Xvoid exit();
  172. Xunsigned sleep();
  173. X#endif
  174. X#ifdef ultrix
  175. Xvoid exit();
  176. Xvoid sleep();
  177. X#endif
  178. X
  179. X#if !defined(MAC) && !defined(MSDOS) && !defined(ATARIST_MWC)
  180. X#ifdef USG
  181. Xstatic struct termio save_termio;
  182. X#else
  183. X#ifndef VMS
  184. Xstatic struct ltchars save_special_chars;
  185. Xstatic struct sgttyb save_ttyb;
  186. Xstatic struct tchars save_tchars;
  187. Xstatic int save_local_chars;
  188. X#endif
  189. X#endif
  190. X#endif
  191. X
  192. X#ifndef MAC
  193. Xstatic int curses_on = FALSE;
  194. Xstatic WINDOW *savescr;        /* Spare window for saving the screen. -CJS- */
  195. X#endif
  196. X
  197. X#ifdef MAC
  198. X/* Attributes of normal and hilighted characters */
  199. X#define ATTR_NORMAL    attrNormal
  200. X#define ATTR_HILITED    attrReversed
  201. X#endif
  202. X
  203. X#ifndef MAC
  204. X#ifdef SIGTSTP
  205. X/* suspend()                               -CJS-
  206. X   Handle the stop and start signals. This ensures that the log
  207. X   is up to date, and that the terminal is fully reset and
  208. X   restored.  */
  209. Xint suspend()
  210. X{
  211. X#ifdef USG
  212. X  /* for USG systems with BSDisms that have SIGTSTP defined, but don't
  213. X     actually implement it */
  214. X#else
  215. X  struct sgttyb tbuf;
  216. X  struct ltchars lcbuf;
  217. X  struct tchars cbuf;
  218. X  int lbuf;
  219. X  long time();
  220. X
  221. X  py.misc.male |= 2;
  222. X  (void) ioctl(0, TIOCGETP, (char *)&tbuf);
  223. X  (void) ioctl(0, TIOCGETC, (char *)&cbuf);
  224. X  (void) ioctl(0, TIOCGLTC, (char *)&lcbuf);
  225. X  (void) ioctl(0, TIOCLGET, (char *)&lbuf);
  226. X  restore_term();
  227. X  (void) kill(0, SIGSTOP);
  228. X  curses_on = TRUE;
  229. X  (void) ioctl(0, TIOCSETP, (char *)&tbuf);
  230. X  (void) ioctl(0, TIOCSETC, (char *)&cbuf);
  231. X  (void) ioctl(0, TIOCSLTC, (char *)&lcbuf);
  232. X  (void) ioctl(0, TIOCLSET, (char *)&lbuf);
  233. X  (void) wrefresh(curscr);
  234. X  py.misc.male &= ~2;
  235. X#endif
  236. X  return 0;
  237. X}
  238. X#endif
  239. X#endif
  240. X
  241. X/* initializes curses routines */
  242. Xvoid init_curses()
  243. X#ifdef MAC
  244. X{
  245. X  /* Primary initialization is done in mac.c since game is restartable */
  246. X  /* Only need to clear the screen here */
  247. X  Rect scrn;
  248. X  
  249. X  scrn.left = scrn.top = 0;
  250. X  scrn.right = SCRN_COLS;
  251. X  scrn.bottom = SCRN_ROWS;
  252. X  EraseScreen(&scrn);
  253. X  UpdateScreen();
  254. X}
  255. X#else
  256. X{
  257. X  int i, y, x;
  258. X
  259. X#ifndef USG
  260. X  (void) ioctl(0, TIOCGLTC, (char *)&save_special_chars);
  261. X  (void) ioctl(0, TIOCGETP, (char *)&save_ttyb);
  262. X  (void) ioctl(0, TIOCGETC, (char *)&save_tchars);
  263. X  (void) ioctl(0, TIOCLGET, (char *)&save_local_chars);
  264. X#else
  265. X#if !defined(VMS) && !defined(MSDOS) && !defined(ATARIST_MWC)
  266. X  (void) ioctl(0, TCGETA, (char *)&save_termio);
  267. X#endif
  268. X#endif
  269. X
  270. X#ifdef ATARIST_MWC
  271. X  WINDOW *newwin();
  272. X  initscr();
  273. X  if (ERR)
  274. X#else
  275. X#if defined(USG) && !defined(PC_CURSES)    /* PC curses returns ERR */
  276. X  if (initscr() == NULL)
  277. X#else
  278. X  if (initscr() == ERR)
  279. X#endif
  280. X#endif
  281. X    {
  282. X      (void) printf("Error allocating screen in curses package.\n");
  283. X      exit(1);
  284. X    }
  285. X  if (LINES < 24 || COLS < 80)     /* Check we have enough screen. -CJS- */
  286. X    {
  287. X      (void) printf("Screen too small for moria.\n");
  288. X      exit (1);
  289. X    }
  290. X#ifdef SIGTSTP
  291. X  (void) signal (SIGTSTP, suspend);
  292. X#endif
  293. X  if ((savescr = newwin (0, 0, 0, 0)) == NULL)
  294. X    {
  295. X      (void) printf ("Out of memory in starting up curses.\n");
  296. X      exit_game();
  297. X    }
  298. X  (void) clear();
  299. X  (void) refresh();
  300. X  moriaterm ();
  301. X
  302. X  /* check tab settings, exit with error if they are not 8 spaces apart */
  303. X#ifdef ATARIST_MWC
  304. X  move(0, 0);
  305. X#else
  306. X  (void) move(0, 0);
  307. X#endif
  308. X  for (i = 1; i < 10; i++)
  309. X    {
  310. X#ifdef ATARIST_MWC
  311. X      addch('\t');
  312. X#else
  313. X      (void) addch('\t');
  314. X#endif
  315. X      getyx(stdscr, y, x);
  316. X      if (y != 0 || x != i*8)
  317. X    break;
  318. X    }
  319. X  if (i != 10)
  320. X    {
  321. X      msg_print("Tabs must be set 8 spaces apart.");
  322. X      exit_game();
  323. X    }
  324. X}
  325. X#endif
  326. X
  327. X/* Set up the terminal into a suitable state for moria.     -CJS- */
  328. Xvoid moriaterm()
  329. X#ifdef MAC
  330. X/* Nothing to do on Mac */
  331. X{
  332. X}
  333. X#else
  334. X{
  335. X#if !defined(MSDOS) && !defined(ATARIST_MWC)
  336. X#ifdef USG
  337. X  struct termio tbuf;
  338. X#else
  339. X  struct ltchars lbuf;
  340. X  struct tchars buf;
  341. X#endif
  342. X#endif
  343. X
  344. X  curses_on = TRUE;
  345. X#ifndef BSD4_3
  346. X  use_value crmode();
  347. X#else
  348. X  use_value cbreak();
  349. X#endif
  350. X  use_value noecho();
  351. X  /* can not use nonl(), because some curses do not handle it correctly */
  352. X#ifdef MSDOS
  353. X  msdos_raw();
  354. X#else
  355. X#if !defined(ATARIST_MWC)
  356. X#ifdef USG
  357. X  (void) ioctl(0, TCGETA, (char *)&tbuf);
  358. X  /* disable all of the normal special control characters */
  359. X  tbuf.c_cc[VINTR] = (char)3; /* control-C */
  360. X  tbuf.c_cc[VQUIT] = (char)-1;
  361. X  tbuf.c_cc[VERASE] = (char)-1;
  362. X  tbuf.c_cc[VKILL] = (char)-1;
  363. X  tbuf.c_cc[VEOF] = (char)-1;
  364. X
  365. X  /* don't know what these are for */
  366. X  tbuf.c_cc[VEOL] = (char)-1;
  367. X  tbuf.c_cc[VEOL2] = (char)-1;
  368. X
  369. X  /* stuff needed when !icanon, i.e. cbreak/raw mode */
  370. X  tbuf.c_cc[VMIN] = 1;  /* Input should wait for at least 1 char */
  371. X  tbuf.c_cc[VTIME] = 0; /* no matter how long that takes. */
  372. X
  373. X  (void) ioctl(0, TCSETA, (char *)&tbuf);
  374. X#else
  375. X#ifndef VMS
  376. X  /* disable all of the special characters except the suspend char, interrupt
  377. X     char, and the control flow start/stop characters */
  378. X  (void) ioctl(0, TIOCGLTC, (char *)&lbuf);
  379. X  lbuf.t_suspc = (char)26; /* control-Z */
  380. X  lbuf.t_dsuspc = (char)-1;
  381. X  lbuf.t_rprntc = (char)-1;
  382. X  lbuf.t_flushc = (char)-1;
  383. X  lbuf.t_werasc = (char)-1;
  384. X  lbuf.t_lnextc = (char)-1;
  385. X  (void) ioctl(0, TIOCSLTC, (char *)&lbuf);
  386. X
  387. X  (void) ioctl (0, TIOCGETC, (char *)&buf);
  388. X  buf.t_intrc = (char)3; /* control-C */
  389. X  buf.t_quitc = (char)-1;
  390. X  buf.t_startc = (char)17; /* control-Q */
  391. X  buf.t_stopc = (char)19; /* control-S */
  392. X  buf.t_eofc = (char)-1;
  393. X  buf.t_brkc = (char)-1;
  394. X  (void) ioctl(0, TIOCSETC, (char *)&buf);
  395. X#endif
  396. X#endif
  397. X#endif
  398. X#endif
  399. X}
  400. X#endif
  401. X
  402. X
  403. X/* Dump IO to buffer                    -RAK-    */
  404. Xvoid put_buffer(out_str, row, col)
  405. Xchar *out_str;
  406. Xint row, col;
  407. X#ifdef MAC
  408. X{
  409. X  /* The screen manager handles writes past the edge ok */
  410. X  DSetScreenCursor(col, row);
  411. X  DWriteScreenStringAttr(out_str, ATTR_NORMAL);
  412. X}    
  413. X#else
  414. X{
  415. X  vtype tmp_str;
  416. X
  417. X  /* truncate the string, to make sure that it won't go past right edge of
  418. X     screen */
  419. X  if (col > 79)
  420. X    col = 79;
  421. X  (void) strncpy (tmp_str, out_str, 79 - col);
  422. X  tmp_str [79 - col] = '\0';
  423. X
  424. X#ifndef ATARIST_MWC
  425. X  if (mvaddstr(row, col, tmp_str) == ERR)
  426. X#else
  427. X  mvaddstr(row, col, out_str);
  428. X  if (ERR)
  429. X#endif
  430. X    {
  431. X      abort();
  432. X      /* clear msg_flag to avoid problems with unflushed messages */
  433. X      msg_flag = 0;
  434. X      (void) sprintf(tmp_str, "error in put_buffer, row = %d col = %d\n",
  435. X             row, col);
  436. X      prt(tmp_str, 0, 0);
  437. X      bell();
  438. X      /* wait so user can see error */
  439. X      (void) sleep(2);
  440. X    }
  441. X}
  442. X#endif
  443. X
  444. X
  445. X/* Dump the IO buffer to terminal            -RAK-    */
  446. Xvoid put_qio()
  447. X{
  448. X  screen_change = TRUE;        /* Let inven_command know something has changed. */
  449. X#ifdef MAC
  450. X  UpdateScreen();
  451. X#else
  452. X  (void) refresh();
  453. X#endif
  454. X}
  455. X
  456. X/* Put the terminal in the original mode.               -CJS- */
  457. Xvoid restore_term()
  458. X#ifdef MAC
  459. X/* Nothing to do on Mac */
  460. X{
  461. X}
  462. X#else
  463. X{
  464. X  if (!curses_on)
  465. X    return;
  466. X  put_qio();  /* Dump any remaining buffer */
  467. X#ifdef MSDOS
  468. X  (void) sleep(2);   /* And let it be read. */
  469. X#endif
  470. X#ifdef VMS
  471. X  pause_line(15);
  472. X#endif
  473. X  /* this moves curses to bottom right corner */
  474. X  mvcur(curscr->_cury, curscr->_curx, LINES-1, 0);
  475. X#ifdef VMS
  476. X  pause_line(15);
  477. X#endif
  478. X  endwin();  /* exit curses */
  479. X  (void) fflush (stdout);
  480. X#ifdef MSDOS
  481. X  msdos_noraw();
  482. X  (void) clear();
  483. X#endif
  484. X  /* restore the saved values of the special chars */
  485. X#ifdef USG
  486. X#if !defined(MSDOS) && !defined(ATARIST_MWC)
  487. X  (void) ioctl(0, TCSETA, (char *)&save_termio);
  488. X#endif
  489. X#else
  490. X#ifndef VMS
  491. X  (void) ioctl(0, TIOCSLTC, (char *)&save_special_chars);
  492. X  (void) ioctl(0, TIOCSETP, (char *)&save_ttyb);
  493. X  (void) ioctl(0, TIOCSETC, (char *)&save_tchars);
  494. X  (void) ioctl(0, TIOCLSET, (char *)&save_local_chars);
  495. X#endif
  496. X#endif
  497. X  curses_on = FALSE;
  498. X}
  499. X#endif
  500. X
  501. X
  502. Xvoid shell_out()
  503. X#ifdef MAC
  504. X{
  505. X  alert_error("This command is not implemented on the Macintosh.");
  506. X}
  507. X#else
  508. X{
  509. X#ifdef USG
  510. X#if !defined(MSDOS) && !defined(ATARIST_MWC)
  511. X  struct termio tbuf;
  512. X#endif
  513. X#else
  514. X  struct sgttyb tbuf;
  515. X  struct ltchars lcbuf;
  516. X  struct tchars cbuf;
  517. X  int lbuf;
  518. X#endif
  519. X#ifdef MSDOS
  520. X  char    *comspec, key;
  521. X#else
  522. X#ifdef ATARIST_MWC
  523. X  char comstr[80];
  524. X  char *str;
  525. X  extern char **environ;
  526. X#else
  527. X  int val;
  528. X  char *str;
  529. X#endif
  530. X#endif
  531. X
  532. X  save_screen();
  533. X  /* clear screen and print 'exit' message */
  534. X  clear_screen();
  535. X#ifndef ATARIST_MWC
  536. X  put_buffer("[Entering shell, type 'exit' to resume your game.]\n",0,0);
  537. X#else
  538. X  put_buffer("[Escaping to shell]\n",0,0);
  539. X#endif
  540. X  put_qio();
  541. X
  542. X#ifdef USG
  543. X#if !defined(MSDOS) && !defined(ATARIST_MWC)
  544. X  (void) ioctl(0, TCGETA, (char *)&tbuf);
  545. X#endif
  546. X#else
  547. X#ifndef VMS
  548. X  (void) ioctl(0, TIOCGETP, (char *)&tbuf);
  549. X  (void) ioctl(0, TIOCGETC, (char *)&cbuf);
  550. X  (void) ioctl(0, TIOCGLTC, (char *)&lcbuf);
  551. X  (void) ioctl(0, TIOCLGET, (char *)&lbuf);
  552. X#endif
  553. X#endif
  554. X  /* would call nl() here if could use nl()/nonl(), see moriaterm() */
  555. X#ifndef BSD4_3
  556. X  use_value nocrmode();
  557. X#else
  558. X  use_value nocbreak();
  559. X#endif
  560. X#ifdef MSDOS
  561. X  use_value msdos_noraw();
  562. X#endif
  563. X  use_value echo();
  564. X  ignore_signals();
  565. X#ifdef MSDOS        /*{*/
  566. X  if ((comspec = getenv("COMSPEC")) == NULL
  567. X  ||  spawnl(P_WAIT, comspec, comspec, (char *) NULL) < 0) {
  568. X    clear_screen();    /* BOSS key if shell failed */
  569. X    put_buffer("M:\\> ", 0, 0);
  570. X    do {
  571. X      key = inkey(key);
  572. X    } while (key != '!');
  573. X  }
  574. X
  575. X#else        /* MSDOS }{*/
  576. X#ifndef ATARIST_MWC
  577. X  val = fork();
  578. X  if (val == 0)
  579. X    {
  580. X#endif
  581. X      default_signals();
  582. X#ifdef USG
  583. X#if !defined(MSDOS) && !defined(ATARIST_MWC)
  584. X      (void) ioctl(0, TCSETA, (char *)&save_termio);
  585. X#endif
  586. X#else
  587. X#ifndef VMS
  588. X      (void) ioctl(0, TIOCSLTC, (char *)&save_special_chars);
  589. X      (void) ioctl(0, TIOCSETP, (char *)&save_ttyb);
  590. X      (void) ioctl(0, TIOCSETC, (char *)&save_tchars);
  591. X      (void) ioctl(0, TIOCLSET, (char *)&save_local_chars);
  592. X#endif
  593. X#endif
  594. X#ifndef MSDOS
  595. X      /* close scoreboard descriptor */
  596. X      /* it is not open on MSDOS machines */
  597. X#if 0
  598. X      /* this file is not open now, see init_file() in files.c */
  599. X      (void) close(highscore_fd);
  600. X#endif
  601. X#endif
  602. X      if (str = getenv("SHELL"))
  603. X#ifndef ATARIST_MWC
  604. X    (void) execl(str, str, (char *) 0);
  605. X#else
  606. X    system(str);
  607. X#endif
  608. X      else
  609. X#ifndef ATARIST_MWC
  610. X    (void) execl("/bin/sh", "sh", (char *) 0);
  611. X#endif
  612. X      msg_print("Cannot execute shell.");
  613. X#ifndef ATARIST_MWC
  614. X      exit(1);
  615. X    }
  616. X  if (val == -1)
  617. X    {
  618. X      msg_print("Fork failed. Try again.");
  619. X      return;
  620. X    }
  621. X#ifdef USG
  622. X  (void) wait((int *) 0);
  623. X#else
  624. X  (void) wait((union wait *) 0);
  625. X#endif
  626. X#endif /* ATARIST_MWC */
  627. X#endif         /* MSDOS }*/
  628. X  restore_signals();
  629. X  /* restore the cave to the screen */
  630. X  restore_screen();
  631. X#ifndef BSD4_3
  632. X  use_value crmode();
  633. X#else
  634. X  use_value cbreak();
  635. X#endif
  636. X  use_value noecho();
  637. X  /* would call nonl() here if could use nl()/nonl(), see moriaterm() */
  638. X#ifdef MSDOS
  639. X  msdos_raw();
  640. X#endif
  641. X  /* disable all of the local special characters except the suspend char */
  642. X  /* have to disable ^Y for tunneling */
  643. X#ifdef USG
  644. X#if !defined(MSDOS) && !defined(ATARIST_MWC)
  645. X  (void) ioctl(0, TCSETA, (char *)&tbuf);
  646. X#endif
  647. X#else
  648. X#ifndef VMS
  649. X  (void) ioctl(0, TIOCSLTC, (char *)&lcbuf);
  650. X  (void) ioctl(0, TIOCSETP, (char *)&tbuf);
  651. X  (void) ioctl(0, TIOCSETC, (char *)&cbuf);
  652. X  (void) ioctl(0, TIOCLSET, (char *)&lbuf);
  653. X#endif
  654. X#endif
  655. X  (void) wrefresh(curscr);
  656. X}
  657. X#endif
  658. X
  659. X
  660. X/* Returns a single character input from the terminal.    This silently -CJS-
  661. X   consumes ^R to redraw the screen and reset the terminal, so that this
  662. X   operation can always be performed at any input prompt.  inkey() never
  663. X   returns ^R.    */
  664. Xchar inkey()
  665. X#ifdef MAC
  666. X/* The Mac does not need ^R, so it just consumes it */
  667. X/* This routine does nothing special with direction keys */
  668. X/* Just returns their keypad ascii value (e.g. '0'-'9') */
  669. X/* Compare with inkeydir() below */
  670. X{
  671. X  char ch;
  672. X  int dir;
  673. X  int shift_flag, ctrl_flag;
  674. X  
  675. X  put_qio();
  676. X  command_count = 0;
  677. X  
  678. X  do {
  679. X    macgetkey(&ch, FALSE);
  680. X  } while (ch == CTRL('R'));
  681. X  
  682. X  dir = extractdir(ch, &shift_flag, &ctrl_flag);
  683. X  if (dir != -1)
  684. X    ch = '0' + dir;
  685. X  
  686. X  return(ch);
  687. X}
  688. X#else
  689. X{
  690. X  int i;
  691. X
  692. X  put_qio();            /* Dump IO buffer        */
  693. X  command_count = 0;  /* Just to be safe -CJS- */
  694. X  while (TRUE)
  695. X    {
  696. X#ifdef MSDOS
  697. X      i = msdos_getch();
  698. X#else
  699. X      i = getch();
  700. X#endif
  701. X
  702. X      /* some machines may not sign extend. */
  703. X      if (i == EOF)
  704. X    {
  705. X      eof_flag++;
  706. X      /* avoid infinite loops while trying to call inkey() for a -more-
  707. X         prompt. */
  708. X      msg_flag = FALSE;
  709. X
  710. X      (void) refresh ();
  711. X      if (!character_generated || character_saved)
  712. X        exit_game();
  713. X      disturb(1, 0);
  714. X      if (eof_flag > 100)
  715. X        {
  716. X          /* just in case, to make sure that the process eventually dies */
  717. X          panic_save = 1;
  718. X          (void) strcpy(died_from, "(end of input: panic saved)");
  719. X          if (!save_char())
  720. X        {
  721. X          (void) strcpy(died_from, "panic: unexpected eof");
  722. X          death = TRUE;
  723. X        }
  724. X          exit_game();
  725. X        }
  726. X      return ESCAPE;
  727. X    }
  728. X      if (i != CTRL('R'))
  729. X    return (char)i;
  730. X      (void) wrefresh (curscr);
  731. X      moriaterm();
  732. X    }
  733. X}
  734. X#endif
  735. X
  736. X
  737. X#ifdef MAC
  738. Xchar inkeydir()
  739. X/* The Mac does not need ^R, so it just consumes it */
  740. X/* This routine translates the direction keys in rogue-like mode */
  741. X/* Compare with inkeydir() below */
  742. X{
  743. X  char ch;
  744. X  int dir;
  745. X  int shift_flag, ctrl_flag;
  746. X  static char tab[9] = {
  747. X    'b',        'j',        'n',
  748. X    'h',        '.',        'l',
  749. X    'y',        'k',        'u'
  750. X  };
  751. X  static char shifttab[9] = {
  752. X    'B',        'J',        'N',
  753. X    'H',        '.',        'L',
  754. X    'Y',        'K',        'U'
  755. X  };
  756. X  static char ctrltab[9] = {
  757. X    CTRL('B'),    CTRL('J'),    CTRL('N'),
  758. X    CTRL('H'),    '.',        CTRL('L'),
  759. X    CTRL('Y'),    CTRL('K'),    CTRL('U')
  760. X  };
  761. X  
  762. X  put_qio();
  763. X  command_count = 0;
  764. X  
  765. X  do {
  766. X    macgetkey(&ch, FALSE);
  767. X  } while (ch == CTRL('R'));
  768. X  
  769. X  dir = extractdir(ch, &shift_flag, &ctrl_flag);
  770. X  
  771. X  if (dir != -1) {
  772. X    if (!rogue_like_commands) {
  773. X      ch = '0' + dir;
  774. X    }
  775. X    else {
  776. X      if (ctrl_flag)
  777. X    ch = ctrltab[dir - 1];
  778. X      else if (shift_flag)
  779. X    ch = shifttab[dir - 1];
  780. X      else
  781. X    ch = tab[dir - 1];
  782. X    }
  783. X  }
  784. X  
  785. X  return(ch);
  786. X}
  787. X#endif
  788. X
  789. X
  790. X/* Flush the buffer                    -RAK-    */
  791. Xvoid flush()
  792. X#ifdef MAC
  793. X{
  794. X/* Removed put_qio() call.  Reduces flashing.  Doesn't seem to hurt. */
  795. X  FlushScreenKeys();
  796. X}
  797. X#else
  798. X{
  799. X#ifdef MSDOS
  800. X  while (kbhit())
  801. X    (void) getch();
  802. X#else
  803. X  /* the code originally used ioctls, TIOCDRAIN, or TIOCGETP/TIOCSETP, or
  804. X     TCGETA/TCSETAF, however this occasionally resulted in loss of output,
  805. X     the happened especially often when rlogin from BSD to SYS_V machine,
  806. X     using check_input makes the desired effect a bit clearer */
  807. X  /* wierd things happen on EOF, don't try to flush input in that case */
  808. X  if (!eof_flag)
  809. X    while (check_input(0));
  810. X#endif
  811. X
  812. X  /* used to call put_qio() here to drain output, but it is not necessary */
  813. X}
  814. X#endif
  815. X
  816. X
  817. X/* Clears given line of text                -RAK-    */
  818. Xvoid erase_line(row, col)
  819. Xint row;
  820. Xint col;
  821. X#ifdef MAC
  822. X{
  823. X  Rect line;
  824. X  
  825. X  if (row == MSG_LINE && msg_flag)
  826. X    msg_print(NULL);
  827. X    
  828. X  line.left = col;
  829. X  line.top = row;
  830. X  line.right = SCRN_COLS;
  831. X  line.bottom = row + 1;
  832. X  DEraseScreen(&line);
  833. X}
  834. X#else
  835. X{
  836. X  if (row == MSG_LINE && msg_flag)
  837. X    msg_print(NULL);
  838. X  (void) move(row, col);
  839. X  clrtoeol();
  840. X}
  841. X#endif
  842. X
  843. X
  844. X/* Clears screen */
  845. Xvoid clear_screen()
  846. X#ifdef MAC
  847. X{
  848. X  Rect area;
  849. X  
  850. X  if (msg_flag)
  851. X    msg_print(NULL);
  852. X    
  853. X  area.left = area.top = 0;
  854. X  area.right = SCRN_COLS;
  855. X  area.bottom = SCRN_ROWS;
  856. X  DEraseScreen(&area);
  857. X}
  858. X#else
  859. X{
  860. X  if (msg_flag)
  861. X    msg_print(NULL);
  862. X  (void) clear();
  863. X}
  864. X#endif
  865. X
  866. Xvoid clear_from (row)
  867. Xint row;
  868. X#ifdef MAC
  869. X{
  870. X  Rect area;
  871. X  
  872. X  area.left = 0;
  873. X  area.top = row;
  874. X  area.right = SCRN_COLS;
  875. X  area.bottom = SCRN_ROWS;
  876. X  DEraseScreen(&area);
  877. X}
  878. X#else
  879. X{
  880. X  (void) move(row, 0);
  881. X  clrtobot();
  882. X}
  883. X#endif
  884. X
  885. X
  886. X/* Outputs a char to a given interpolated y, x position    -RAK-    */
  887. X/* sign bit of a character used to indicate standout mode. -CJS */
  888. Xvoid print(ch, row, col)
  889. Xchar ch;
  890. Xint row;
  891. Xint col;
  892. X#ifdef MAC
  893. X{
  894. X  char cnow, anow;
  895. X  
  896. X  row -= panel_row_prt;/* Real co-ords convert to screen positions */
  897. X  col -= panel_col_prt;
  898. X  
  899. X  GetScreenCharAttr(&cnow, &anow, col, row);    /* Check current */
  900. X  
  901. X  /* If char is already set, ignore op */
  902. X  if ((cnow != ch) || (anow != ATTR_NORMAL))
  903. X    DSetScreenCharAttr(cnew, anew, col, row);
  904. X}
  905. X#else
  906. X{
  907. X  vtype tmp_str;
  908. X
  909. X  row -= panel_row_prt;/* Real co-ords convert to screen positions */
  910. X  col -= panel_col_prt;
  911. X#if defined(ATARIST_MWC)
  912. X  mvaddch (row, col, ch);
  913. X#else
  914. X  if (mvaddch (row, col, ch) == ERR)
  915. X    {
  916. X      abort();
  917. X      /* clear msg_flag to avoid problems with unflushed messages */
  918. X      msg_flag = 0;
  919. X      (void) sprintf(tmp_str, "error in print, row = %d col = %d\n", row, col);
  920. X      prt(tmp_str, 0, 0);
  921. X      bell ();
  922. X      /* wait so user can see error */
  923. X      (void) sleep(2);
  924. X    }
  925. X#endif
  926. X}
  927. X#endif
  928. X
  929. X
  930. X/* Moves the cursor to a given interpolated y, x position    -RAK-    */
  931. Xvoid move_cursor_relative(row, col)
  932. Xint row;
  933. Xint col;
  934. X#ifdef MAC
  935. X{
  936. X  row -= panel_row_prt;/* Real co-ords convert to screen positions */
  937. X  col -= panel_col_prt;
  938. X  
  939. X  DSetScreenCursor(col, row);
  940. X}
  941. X#else
  942. X{
  943. X  vtype tmp_str;
  944. X
  945. X  row -= panel_row_prt;/* Real co-ords convert to screen positions */
  946. X  col -= panel_col_prt;
  947. X  if (move (row, col) == ERR)
  948. X    {
  949. X      abort();
  950. X      /* clear msg_flag to avoid problems with unflushed messages */
  951. X      msg_flag = 0;
  952. X      (void) sprintf(tmp_str, "error in move_cursor_relative, row = %d col = %d\n", row, col);
  953. X      prt(tmp_str, 0, 0);
  954. X      bell();
  955. X      /* wait so user can see error */
  956. X      (void) sleep(2);
  957. X    }
  958. X}
  959. X#endif
  960. X
  961. X
  962. X/* Print a message so as not to interrupt a counted command. -CJS- */
  963. Xvoid count_msg_print(p)
  964. Xchar *p;
  965. X{
  966. X  int i;
  967. X
  968. X  i = command_count;
  969. X  msg_print(p);
  970. X  command_count = i;
  971. X}
  972. X
  973. X
  974. X/* Outputs a line to a given y, x position        -RAK-    */
  975. Xvoid prt(str_buff, row, col)
  976. Xchar *str_buff;
  977. Xint row;
  978. Xint col;
  979. X#ifdef MAC
  980. X{
  981. X  Rect line;
  982. X  
  983. X  if (row == MSG_LINE && msg_flag)
  984. X    msg_print(NULL);
  985. X    
  986. X  line.left = col;
  987. X  line.top = row;
  988. X  line.right = SCRN_COLS;
  989. X  line.bottom = row + 1;
  990. X  DEraseScreen(&line);
  991. X  
  992. X  put_buffer(str_buff, row, col);
  993. X}
  994. X#else
  995. X{
  996. X  if (row == MSG_LINE && msg_flag)
  997. X    msg_print(NULL);
  998. X  (void) move(row, col);
  999. X  clrtoeol();
  1000. X  put_buffer(str_buff, row, col);
  1001. X}
  1002. X#endif
  1003. X
  1004. X
  1005. X/* move cursor to a given y, x position */
  1006. Xvoid move_cursor(row, col)
  1007. Xint row, col;
  1008. X#ifdef MAC
  1009. X{
  1010. X  DSetScreenCursor(col, row);
  1011. X}
  1012. X#else
  1013. X{
  1014. X  (void) move (row, col);
  1015. X}
  1016. X#endif
  1017. X
  1018. X
  1019. X/* Outputs message to top line of screen                */
  1020. X/* These messages are kept for later reference.     */
  1021. Xvoid msg_print(str_buff)
  1022. Xchar *str_buff;
  1023. X{
  1024. X  register int old_len;
  1025. X  char in_char;
  1026. X#ifdef MAC
  1027. X  Rect line;
  1028. X#endif
  1029. X
  1030. X  if (msg_flag)
  1031. X    {
  1032. X      old_len = strlen(old_msg[last_msg]) + 1;
  1033. X      /* ensure that the complete -more- message is visible. */
  1034. X      if (old_len > 73)
  1035. X    old_len = 73;
  1036. X      put_buffer(" -more-", MSG_LINE, old_len);
  1037. X      /* let sigint handler know that we are waiting for a space */
  1038. X      wait_for_more = 1;
  1039. X      do
  1040. X    {
  1041. X      in_char = inkey();
  1042. X    }
  1043. X      while ((in_char != ' ') && (in_char != ESCAPE) && (in_char != '\n') &&
  1044. X         (in_char != '\r'));
  1045. X      wait_for_more = 0;
  1046. X    }
  1047. X#ifdef MAC
  1048. X  line.left = 0;
  1049. X  line.top = MSG_LINE;
  1050. X  line.right = SCRN_COLS;
  1051. X  line.bottom = MSG_LINE+1;
  1052. X  DEraseScreen(&line);
  1053. X#else
  1054. X  (void) move(MSG_LINE, 0);
  1055. X  clrtoeol();
  1056. X#endif
  1057. X
  1058. X  /* Make the null string a special case.  -CJS- */
  1059. X  if (str_buff)
  1060. X    {
  1061. X      put_buffer(str_buff, MSG_LINE, 0);
  1062. X      command_count = 0;
  1063. X      last_msg++;
  1064. X      if (last_msg >= MAX_SAVE_MSG)
  1065. X    last_msg = 0;
  1066. X      (void) strncpy(old_msg[last_msg], str_buff, VTYPESIZ);
  1067. X      old_msg[last_msg][VTYPESIZ - 1] = '\0';
  1068. X      msg_flag = TRUE;
  1069. X    }
  1070. X  else
  1071. X    msg_flag = FALSE;
  1072. X}
  1073. X
  1074. X
  1075. X/* Used to verify a choice - user gets the chance to abort choice.  -CJS- */
  1076. Xint get_check(prompt)
  1077. Xchar *prompt;
  1078. X{
  1079. X  int res;
  1080. X  int y, x;
  1081. X
  1082. X  prt(prompt, 0, 0);
  1083. X#ifdef MAC
  1084. X  GetScreenCursor(&x, &y);
  1085. X#else
  1086. X  getyx(stdscr, y, x);
  1087. X#if defined(lint)
  1088. X  /* prevent message 'warning: y is unused' */
  1089. X  x = y;
  1090. X#endif
  1091. X#endif
  1092. X
  1093. X  if (x > 73)
  1094. X#ifdef ATARIST_MWC
  1095. X    move(0, 73);
  1096. X#else
  1097. X    (void) move(0, 73);
  1098. X#endif
  1099. X#ifdef MAC
  1100. X  DWriteScreenStringAttr(" [y/n]", ATTR_NORMAL);
  1101. X#else
  1102. X  (void) addstr(" [y/n]");
  1103. X#endif
  1104. X  do
  1105. X    {
  1106. X      res = inkey();
  1107. X    }
  1108. X  while(res == ' ');
  1109. X  erase_line(0, 0);
  1110. X  if (res == 'Y' || res == 'y')
  1111. X    return TRUE;
  1112. X  else
  1113. X    return FALSE;
  1114. X}
  1115. X
  1116. X/* Prompts (optional) and returns ord value of input char    */
  1117. X/* Function returns false if <ESCAPE> is input    */
  1118. Xint get_com(prompt, command)
  1119. Xchar *prompt;
  1120. Xchar *command;
  1121. X{
  1122. X  int res;
  1123. X
  1124. X  if (prompt)
  1125. X    prt(prompt, 0, 0);
  1126. X  *command = inkey();
  1127. X  if (*command == 0 || *command == ESCAPE)
  1128. X    res = FALSE;
  1129. X  else
  1130. X    res = TRUE;
  1131. X  erase_line(MSG_LINE, 0);
  1132. X  return(res);
  1133. X}
  1134. X
  1135. X#ifdef MAC
  1136. X/* Same as get_com(), but translates direction keys from keypad */
  1137. Xint get_comdir(prompt, command)
  1138. Xchar *prompt;
  1139. Xchar *command;
  1140. X{
  1141. X  int res;
  1142. X
  1143. X  if (prompt)
  1144. X    prt(prompt, 0, 0);
  1145. X  *command = inkeydir();
  1146. X  if (*command == 0 || *command == ESCAPE)
  1147. X    res = FALSE;
  1148. X  else
  1149. X    res = TRUE;
  1150. X  erase_line(MSG_LINE, 0);
  1151. X  return(res);
  1152. X}
  1153. X#endif
  1154. X
  1155. X
  1156. X/* Gets a string terminated by <RETURN>        */
  1157. X/* Function returns false if <ESCAPE> is input    */
  1158. Xint get_string(in_str, row, column, slen)
  1159. Xchar *in_str;
  1160. Xint row, column, slen;
  1161. X{
  1162. X  register int start_col, end_col, i;
  1163. X  char *p;
  1164. X  int flag, aborted;
  1165. X#ifdef MAC
  1166. X  Rect area;
  1167. X#endif
  1168. X
  1169. X  aborted = FALSE;
  1170. X  flag    = FALSE;
  1171. X#ifdef MAC
  1172. X  area.left = column;
  1173. X  area.top = row;
  1174. X  area.right = column + slen;
  1175. X  area.bottom = row + 1;
  1176. X  DEraseScreen(&area);
  1177. X  DSetScreenCursor(column, row);
  1178. X#else
  1179. X  (void) move(row, column);
  1180. X  for (i = slen; i > 0; i--)
  1181. X    (void) addch(' ');
  1182. X  (void) move(row, column);
  1183. X#endif
  1184. X  start_col = column;
  1185. X  end_col = column + slen - 1;
  1186. X  if (end_col > 79)
  1187. X    {
  1188. X      slen = 80 - column;
  1189. X      end_col = 79;
  1190. X    }
  1191. X  p = in_str;
  1192. X  do
  1193. X    {
  1194. X      i = inkey();
  1195. X      switch(i)
  1196. X    {
  1197. X    case ESCAPE:
  1198. X      aborted = TRUE;
  1199. X      break;
  1200. X    case CTRL('J'): case CTRL('M'):
  1201. X      flag    = TRUE;
  1202. X      break;
  1203. X    case DELETE: case CTRL('H'):
  1204. X      if (column > start_col)
  1205. X        {
  1206. X          column--;
  1207. X          put_buffer(" ", row, column);
  1208. X          move_cursor(row, column);
  1209. X          *--p = '\0';
  1210. X        }
  1211. X      break;
  1212. X    default:
  1213. X      if (!isprint(i) || column > end_col)
  1214. X        bell();
  1215. X      else
  1216. X        {
  1217. X#ifdef MAC
  1218. X          DSetScreenCursor(column, row);
  1219. X          DWriteScreenCharAttr((char) i, ATTR_NORMAL);
  1220. X#else
  1221. X          use_value2 mvaddch(row, column, (char)i);
  1222. X#endif
  1223. X          *p++ = i;
  1224. X          column++;
  1225. X        }
  1226. X      break;
  1227. X    }
  1228. X    }
  1229. X  while ((!flag) && (!aborted));
  1230. X  if (aborted)
  1231. X    return(FALSE);
  1232. X  /* Remove trailing blanks    */
  1233. X  while (p > in_str && p[-1] == ' ')
  1234. X    p--;
  1235. X  *p = '\0';
  1236. X  return(TRUE);
  1237. X}
  1238. X
  1239. X
  1240. X/* Pauses for user response before returning        -RAK-    */
  1241. Xvoid pause_line(prt_line)
  1242. Xint prt_line;
  1243. X{
  1244. X  prt("[Press any key to continue.]", prt_line, 23);
  1245. X  (void) inkey();
  1246. X  erase_line(prt_line, 0);
  1247. X}
  1248. X
  1249. X
  1250. X/* Pauses for user response before returning        -RAK-    */
  1251. X/* NOTE: Delay is for players trying to roll up "perfect"    */
  1252. X/*    characters.  Make them wait a bit.            */
  1253. Xvoid pause_exit(prt_line, delay)
  1254. Xint prt_line;
  1255. Xint delay;
  1256. X{
  1257. X  char dummy;
  1258. X
  1259. X  prt("[Press any key to continue, or Q to exit.]", prt_line, 10);
  1260. X  dummy = inkey();
  1261. X  if (dummy == 'Q')
  1262. X    {
  1263. X      erase_line(prt_line, 0);
  1264. X#ifndef MSDOS        /* PCs are slow enough as is  -dgk */
  1265. X      if (delay > 0)  (void) sleep((unsigned)delay);
  1266. X#endif
  1267. X#ifdef MAC
  1268. X      enablefilemenu(FALSE);
  1269. X      exit_game();
  1270. X      enablefilemenu(TRUE);
  1271. X#else
  1272. X      exit_game();
  1273. X#endif
  1274. X    }
  1275. X  erase_line(prt_line, 0);
  1276. X}
  1277. X
  1278. X#ifdef MAC
  1279. Xvoid save_screen()
  1280. X{
  1281. X  mac_save_screen();
  1282. X}
  1283. X
  1284. Xvoid restore_screen()
  1285. X{
  1286. X  mac_restore_screen();
  1287. X}
  1288. X#else
  1289. Xvoid save_screen()
  1290. X{
  1291. X  overwrite(stdscr, savescr);
  1292. X}
  1293. X
  1294. Xvoid restore_screen()
  1295. X{
  1296. X  overwrite(savescr, stdscr);
  1297. X  touchwin(stdscr);
  1298. X}
  1299. X#endif
  1300. X
  1301. Xvoid bell()
  1302. X{
  1303. X  put_qio();
  1304. X#ifdef MAC
  1305. X  mac_beep();
  1306. X#else
  1307. X  (void) write(1, "\007", 1);
  1308. X#endif
  1309. X}
  1310. X
  1311. X/* definitions used by screen_map() */
  1312. X/* index into border character array */
  1313. X#define TL 0    /* top left */
  1314. X#define TR 1
  1315. X#define BL 2
  1316. X#define BR 3
  1317. X#define HE 4    /* horizontal edge */
  1318. X#define VE 5
  1319. X
  1320. X/* character set to use */
  1321. X#ifdef MSDOS
  1322. X# ifdef ANSI
  1323. X#   define CH(x)    (ansi ? screen_border[0][x] : screen_border[1][x])
  1324. X# else
  1325. X#   define CH(x)    (screen_border[1][x])
  1326. X# endif
  1327. X#else
  1328. X#   define CH(x)    (screen_border[0][x])
  1329. X#endif
  1330. X
  1331. X  /* Display highest priority object in the RATIO by RATIO area */
  1332. X#define    RATIO 3
  1333. X
  1334. Xvoid screen_map()
  1335. X{
  1336. X  register int    i, j;
  1337. X  static int8u screen_border[2][6] = {
  1338. X    {'+', '+', '+', '+', '-', '|'},    /* normal chars */
  1339. X    {201, 187, 200, 188, 205, 186}    /* graphics chars */
  1340. X  };
  1341. X  int8u map[MAX_WIDTH / RATIO + 1];
  1342. X  int8u tmp;
  1343. X  int priority[256];
  1344. X  int row, orow, col, myrow, mycol = 0;
  1345. X#ifndef MAC
  1346. X  char prntscrnbuf[80];
  1347. X#endif
  1348. X
  1349. X  for (i = 0; i < 256; i++)
  1350. X    priority[i] = 0;
  1351. X  priority['<'] = 5;
  1352. X  priority['>'] = 5;
  1353. X  priority['@'] = 10;
  1354. X#ifdef MSDOS
  1355. X  priority[wallsym] = -5;
  1356. X  priority[floorsym] = -10;
  1357. X#else
  1358. X  priority['#'] = -5;
  1359. X  priority['.'] = -10;
  1360. X#endif
  1361. X  priority['\''] = -3;
  1362. X  priority[' '] = -15;
  1363. X
  1364. X  save_screen();
  1365. X  clear_screen();
  1366. X#ifdef MAC
  1367. X  DSetScreenCursor(0, 0);
  1368. X  DWriteScreenCharAttr(CH(TL), ATTR_NORMAL);
  1369. X  for (i = 0; i < MAX_WIDTH / RATIO; i++)
  1370. X    DWriteScreenCharAttr(CH(HE), ATTR_NORMAL);
  1371. X  DWriteScreenCharAttr(CH(TR), ATTR_NORMAL);
  1372. X#else
  1373. X  use_value2 mvaddch(0, 0, CH(TL));
  1374. X  for (i = 0; i < MAX_WIDTH / RATIO; i++)
  1375. X    (void) addch(CH(HE));
  1376. X  (void) addch(CH(TR));
  1377. X#endif
  1378. X  orow = -1;
  1379. X  map[MAX_WIDTH / RATIO] = '\0';
  1380. X  for (i = 0; i < MAX_HEIGHT; i++)
  1381. X    {
  1382. X      row = i / RATIO;
  1383. X      if (row != orow)
  1384. X    {
  1385. X      if (orow >= 0)
  1386. X        {
  1387. X#ifdef MAC
  1388. X          DSetScreenCursor(0, orow+1);
  1389. X          DWriteScreenCharAttr(CH(VE), ATTR_NORMAL);
  1390. X          DWriteScreenString(map);
  1391. X          DWriteScreenCharAttr(CH(VE), ATTR_NORMAL);
  1392. X#else
  1393. X          /* can not use mvprintw() on ibmpc, because PC-Curses is horribly
  1394. X         written, and mvprintw() causes the fp emulation library to be
  1395. X         linked with PC-Moria, makes the program 10K bigger */
  1396. X          (void) sprintf(prntscrnbuf,"%c%s%c",CH(VE), map, CH(VE));
  1397. X          use_value2 mvaddstr(orow+1, 0, prntscrnbuf);
  1398. X#endif
  1399. X        }
  1400. X      for (j = 0; j < MAX_WIDTH / RATIO; j++)
  1401. X        map[j] = ' ';
  1402. X      orow = row;
  1403. X    }
  1404. X      for (j = 0; j < MAX_WIDTH; j++)
  1405. X    {
  1406. X      col = j / RATIO;
  1407. X      tmp = loc_symbol(i, j);
  1408. X      if (priority[map[col]] < priority[tmp])
  1409. X        map[col] = tmp;
  1410. X      if (map[col] == '@')
  1411. X        {
  1412. X          mycol = col + 1; /* account for border */
  1413. X          myrow = row + 1;
  1414. X        }
  1415. X    }
  1416. X    }
  1417. X  if (orow >= 0)
  1418. X    {
  1419. X#ifdef MAC
  1420. X      DSetScreenCursor(0, orow+1);
  1421. X      DWriteScreenCharAttr(CH(VE), ATTR_NORMAL);
  1422. X      DWriteScreenString(map);
  1423. X      DWriteScreenCharAttr(CH(VE), ATTR_NORMAL);
  1424. X#else
  1425. X      (void) sprintf(prntscrnbuf,"%c%s%c",CH(VE), map, CH(VE));
  1426. X      use_value2 mvaddstr(orow+1, 0, prntscrnbuf);
  1427. X#endif
  1428. X    }
  1429. X#ifdef MAC
  1430. X  DSetScreenCursor(0, orow + 2);
  1431. X  DWriteScreenCharAttr(CH(BL), ATTR_NORMAL);
  1432. X  for (i = 0; i < MAX_WIDTH / RATIO; i++)
  1433. X    DWriteScreenCharAttr(CH(HE), ATTR_NORMAL);
  1434. X  DWriteScreenCharAttr(CH(BR), ATTR_NORMAL);
  1435. X#else
  1436. X  use_value2 mvaddch(orow + 2, 0, CH(BL));
  1437. X  for (i = 0; i < MAX_WIDTH / RATIO; i++)
  1438. X    (void) addch(CH(HE));
  1439. X  (void) addch(CH(BR));
  1440. X#endif
  1441. X
  1442. X#ifdef MAC
  1443. X  DSetScreenCursor(23, 23);
  1444. X  DWriteScreenStringAttr("Hit any key to continue", ATTR_NORMAL);
  1445. X  if (mycol > 0)
  1446. X    DSetScreenCursor(mycol, myrow);
  1447. X#else
  1448. X  use_value2 mvaddstr(23, 23, "Hit any key to continue");
  1449. X  if (mycol > 0)
  1450. X    (void) move(myrow, mycol);
  1451. X#endif
  1452. X  (void) inkey();
  1453. X  restore_screen();
  1454. X}
  1455. END_OF_FILE
  1456. if test 29702 -ne `wc -c <'source/io.c'`; then
  1457.     echo shar: \"'source/io.c'\" unpacked with wrong size!
  1458. fi
  1459. # end of 'source/io.c'
  1460. fi
  1461. if test -f 'util/mc/creature.y' -a "${1}" != "-c" ; then 
  1462.   echo shar: Will not clobber existing file \"'util/mc/creature.y'\"
  1463. else
  1464. echo shar: Extracting \"'util/mc/creature.y'\" \(26718 characters\)
  1465. sed "s/^X//" >'util/mc/creature.y' <<'END_OF_FILE'
  1466. X/*
  1467. X * creature_comp.y
  1468. X *    a Moria creature definition compiler
  1469. X *
  1470. X * Copyright 1989 by Joseph Hall.
  1471. X * All rights reserved except as stated below.
  1472. X * This program may contain portions excerpted from Moria which are
  1473. X * copyrighted by others.
  1474. X *
  1475. X * Jim Wilson and any other holders of copyright on substantial portions
  1476. X * of Moria are granted rights to use, modify, and distribute this program
  1477. X * as they see fit, so long as the terms of its use, modification and/or
  1478. X * distribution are no less restrictive than those applying to Moria,
  1479. X * version 5.0 or later, itself, and so long as this use is related to
  1480. X * the further development of Moria.
  1481. X *
  1482. X * Anyone having any other use in mind for this code should contact the
  1483. X * author at 4116 Brewster Dr., Raleigh NC 27606 (jnh@ecemwl.ncsu.edu).
  1484. X */
  1485. X
  1486. X%{
  1487. X#include <stdio.h>
  1488. X#include <string.h>
  1489. X#include <ctype.h>
  1490. X#include <math.h>
  1491. X
  1492. X#ifdef ANSI_LIBS
  1493. X#include <stdlib.h>
  1494. X#else
  1495. Xextern double atof();
  1496. Xextern char *malloc();
  1497. Xextern char *calloc();
  1498. Xextern void free();
  1499. X#endif
  1500. X
  1501. X#include "st.h"
  1502. X
  1503. X#ifndef TRUE
  1504. X#define TRUE 1
  1505. X#endif
  1506. X
  1507. X#ifndef FALSE
  1508. X#define FALSE 0
  1509. X#endif
  1510. X
  1511. X#define VERBOSE /* to turn on debugging output */
  1512. X
  1513. Xtypedef unsigned long  int32u;
  1514. Xtypedef long           int32;
  1515. Xtypedef unsigned short int16u;
  1516. Xtypedef short          int16;
  1517. Xtypedef unsigned char  int8u;
  1518. X
  1519. Xtypedef struct creature_type
  1520. X{
  1521. X  char *name;           /* Descrip of creature  */
  1522. X  int32u cmove;         /* Bit field            */
  1523. X  int32u spells;        /* Creature spells      */
  1524. X  int16u cdefense;      /* Bit field            */
  1525. X  int16u mexp;          /* Exp value for kill   */
  1526. X  int8u sleep;          /* Inactive counter/10  */
  1527. X  int8u aaf;            /* Area affect radius   */
  1528. X  int8u ac;             /* AC                   */
  1529. X  int8u speed;          /* Movement speed+10    */
  1530. X  int8u cchar;          /* Character rep.       */
  1531. X  int8u hd[2];          /* Creatures hit die    */
  1532. X  int8u damage[4];      /* Type attack and damage*/
  1533. X  int8u level;          /* Level of creature    */
  1534. X
  1535. X    int32u general;    /* general characteristics; not present in usual */
  1536. X            /* moria creature_type */
  1537. X} creature_type;
  1538. X
  1539. X
  1540. X
  1541. X/*
  1542. X * defined_t is used to indicate whether all fields have been defined
  1543. X */
  1544. X
  1545. Xtypedef struct {
  1546. X    unsigned    move: 1,
  1547. X        special: 1,
  1548. X        treasure: 1,
  1549. X        spell: 1,
  1550. X        breath: 1,
  1551. X        defense: 1,
  1552. X        mexp: 1,
  1553. X        sleep: 1,
  1554. X        aaf: 1,
  1555. X        ac: 1,
  1556. X        speed: 1,
  1557. X        cchar: 1,
  1558. X        hd: 1,
  1559. X        damage: 1,
  1560. X        level: 1;
  1561. X} defined_t;
  1562. X
  1563. X
  1564. X
  1565. X/*
  1566. X * template_t contains creature definition & flags
  1567. X */
  1568. X
  1569. Xtypedef struct {
  1570. X    creature_type    val;
  1571. X    defined_t    def;
  1572. X} template_t;
  1573. X
  1574. X
  1575. X
  1576. X/*
  1577. X * attack_t describes a monster attack
  1578. X */
  1579. X
  1580. Xtypedef struct {
  1581. X    int8u        type,
  1582. X            desc,
  1583. X            dice,
  1584. X            sides;
  1585. X} attack_t;
  1586. X
  1587. X
  1588. X
  1589. X/*
  1590. X * symInit_t is used to initialize symbol tables with integer values
  1591. X */
  1592. X
  1593. Xtypedef struct {
  1594. X    char        *name;
  1595. X    int32u        val;
  1596. X} symInit_t;
  1597. X
  1598. X
  1599. X
  1600. Xstatic symInit_t defenseInit[] = {
  1601. X    { "dragon", 0 },
  1602. X    { "animal", 1 },
  1603. X    { "evil", 2 },
  1604. X    { "undead", 3 },
  1605. X    { "frost", 4 },
  1606. X    { "fire", 5 },
  1607. X    { "poison", 6 },
  1608. X    { "acid", 7 },
  1609. X    { "light", 8 },
  1610. X    { "stone", 9 },
  1611. X    { "bit_9", 10 },
  1612. X    { "bit_10", 11 },
  1613. X    { "no_sleep", 12 },
  1614. X    { "infra", 13 },
  1615. X    { "max_hp", 14 },
  1616. X    { "bit_15", 15 },
  1617. X    { NULL, 0 }
  1618. X};
  1619. X
  1620. Xstatic symInit_t moveInit[] = {
  1621. X    { "attack_only", 0 },
  1622. X    { "move_normal", 1 },
  1623. X    { "bit_2", 2 },
  1624. X    { "random_20", 3 },
  1625. X    { "random_40", 4 },
  1626. X    { "random_75", 5 },
  1627. X    { NULL, 0 }
  1628. X};
  1629. X
  1630. Xstatic symInit_t specialInit[] = {
  1631. X    { "invisible", 16 },
  1632. X    { "open_door", 17 },
  1633. X    { "phase", 18 },
  1634. X    { "eats_other", 19 },
  1635. X    { "picks_up", 20 },
  1636. X    { "multiply", 21 },
  1637. X    { "win_creature", 31 },
  1638. X    { NULL, 0 }
  1639. X};
  1640. X
  1641. Xstatic symInit_t treasureInit[] = {
  1642. X    { "carry_obj", 24 },
  1643. X    { "carry_gold", 25 },
  1644. X    { "has_random_60", 26 },
  1645. X    { "has_random_90", 27 },
  1646. X    { "has_1d2_obj", 28 },
  1647. X    { "has_2d2_obj", 29 },
  1648. X    { "has_4d2_obj", 30 },
  1649. X    { NULL, 0 }
  1650. X};
  1651. X
  1652. Xstatic symInit_t spellInit[] = {
  1653. X    { "tel_short", 4 },
  1654. X    { "tel_long", 5 },
  1655. X    { "tel_to", 6 },
  1656. X    { "lght_wnd", 7 },
  1657. X    { "ser_wnd", 8 },
  1658. X    { "hold_per", 9 },
  1659. X    { "blind", 10 },
  1660. X    { "confuse", 11 },
  1661. X    { "fear", 12 },
  1662. X    { "summon_mon", 13 },
  1663. X    { "summon_und", 14 },
  1664. X    { "slow_per", 15 },
  1665. X    { "drain_mana", 16 },
  1666. X    { "bit_17", 17 },
  1667. X    { "bit_18", 18 },
  1668. X    { NULL, 0 }
  1669. X};
  1670. X
  1671. Xstatic symInit_t breathInit[] = {
  1672. X    { "light", 19 },
  1673. X    { "gas", 20 },
  1674. X    { "acid", 21 },
  1675. X    { "frost", 22 },
  1676. X    { "fire", 23 },
  1677. X    { NULL, 0 }
  1678. X};
  1679. X
  1680. Xstatic symInit_t attackTypeInit[] = {
  1681. X    { "normal_damage", 1 },
  1682. X    { "lose_str", 2 },
  1683. X    { "confusion", 3 },
  1684. X    { "cause_fear", 4 },
  1685. X    { "fire_damage", 5 },
  1686. X    { "acid_damage", 6 },
  1687. X    { "cold_damage", 7 },
  1688. X    { "lightning_damage", 8 },
  1689. X    { "corrosion", 9 },
  1690. X    { "cause_blindness", 10 },
  1691. X    { "cause_paralysis", 11 },
  1692. X    { "steal_money", 12 },
  1693. X    { "steal_obj", 13 },
  1694. X    { "poison", 14 },
  1695. X    { "lose_dex", 15 },
  1696. X    { "lose_con", 16 },
  1697. X    { "lose_int", 17 },
  1698. X    { "lose_wis", 18 },
  1699. X    { "lose_exp", 19 },
  1700. X    { "aggravation", 20 },
  1701. X    { "disenchant", 21 },
  1702. X    { "eat_food", 22 },
  1703. X    { "eat_light", 23 },
  1704. X    { "eat_charges", 24 },
  1705. X    { "blank", 99 },
  1706. X    { NULL, 0 }
  1707. X};
  1708. X
  1709. Xstatic symInit_t attackDescInit[] = {
  1710. X    { "hits", 1 },
  1711. X    { "bites", 2 },
  1712. X    { "claws", 3 },
  1713. X    { "stings", 4 },
  1714. X    { "touches", 5 },
  1715. X    { "kicks", 6 },
  1716. X    { "gazes", 7 },
  1717. X    { "breathes", 8 },
  1718. X    { "spits", 9 },
  1719. X    { "wails", 10 },
  1720. X    { "embraces", 11 },
  1721. X    { "crawls_on", 12 },
  1722. X    { "releases_spores", 13 },
  1723. X    { "begs_for_money", 14 },
  1724. X    { "slimes", 15 },
  1725. X    { "crushes", 16 },
  1726. X    { "tramples", 17 },
  1727. X    { "drools_on", 18 },
  1728. X    { "insults", 19 },
  1729. X    { "is_repelled", 99 },
  1730. X    { NULL, 0 }
  1731. X};
  1732. X
  1733. X
  1734. X
  1735. X
  1736. X/*
  1737. X * Maximum token length = maximum string constant length
  1738. X * Also, trim the stack to an "acceptable" size.
  1739. X */
  1740. X
  1741. X#define    MAX_TOK_LEN    64        /* maximum acceptable token length  */
  1742. X#define    YYSTACKSIZE    128
  1743. X
  1744. X#define GEN_TYPE_TMPL    256        /* type of a template for st        */
  1745. X
  1746. X/*
  1747. X * Globals used by the tokenizer (lexical analyzer)
  1748. X */
  1749. X
  1750. X#define INPUT_BUF_SIZE 256
  1751. Xstatic char    inputBuf[INPUT_BUF_SIZE] = { 0 }; 
  1752. X                    /* input line buffer            */
  1753. Xstatic char    *inputBufp = inputBuf;    /* position in input line buffer    */
  1754. Xstatic int    lineNo = 0;        /* number of current line        */
  1755. Xstatic FILE    *input_F;
  1756. Xstatic char    tokStr[MAX_TOK_LEN];    /* text of current token        */
  1757. Xstatic    int    tokType;        /* type of current token        */
  1758. Xstatic    double    tokVal;            /* numeric value of current token,  */
  1759. X                    /* if applicable            */
  1760. X
  1761. Xstatic template_t blankTemplate = { 0 }; /* blank template for init-ing     */
  1762. Xstatic template_t tmpTemplate;        /* working template for current     */
  1763. X                    /* class or creature            */
  1764. X
  1765. X#define MAX_ATTACK 250
  1766. Xstatic attack_t attackList[MAX_ATTACK] = { 0 };
  1767. Xstatic int attackCt = 1, creatureAttacks = 0;
  1768. Xstatic int maxCreatureLevel = 0;
  1769. X
  1770. X/*
  1771. X * Global symbol tables
  1772. X */
  1773. X
  1774. Xstatic st_Table_Pt keywordT_P,        /* parser's keywords            */
  1775. X        defenseT_P,        /* defense flags            */
  1776. X        moveT_P,        /* movement flags            */
  1777. X        specialT_P,        /* special flags            */
  1778. X        treasureT_P,        /* treasure flags            */
  1779. X        spellT_P,        /* spell flags                */
  1780. X        breathT_P,        /* breath flags                */
  1781. X        attackTypeT_P,        /* attack type flags            */
  1782. X        attackDescT_P,        /* attack desc flags            */
  1783. X        classT_P,        /* class templates            */
  1784. X        creatureT_P;        /* creature definitions            */
  1785. X
  1786. X/*
  1787. X * Function declarations
  1788. X */
  1789. X
  1790. Xextern void AddDefense();
  1791. Xextern void NegDefense();
  1792. Xextern void AddMove();
  1793. Xextern void NegMove();
  1794. Xextern void AddTreasure();
  1795. Xextern void NegTreasure();
  1796. Xextern void AddSpecial();
  1797. Xextern void NegSpecial();
  1798. Xextern void AddSpell();
  1799. Xextern void NegSpell();
  1800. Xextern void AddBreath();
  1801. Xextern void NegBreath();
  1802. Xextern void AddAttack();
  1803. Xextern void WriteCreature();
  1804. Xextern void PutClassTemplate();
  1805. Xextern template_t GetClassTemplate();
  1806. Xextern void PutCreature();
  1807. X
  1808. X%}
  1809. X
  1810. X
  1811. X/*
  1812. X * YACC DEFINITIONS
  1813. X */
  1814. X
  1815. X/*
  1816. X * The parser's stack can hold ints, doubles, and strings.
  1817. X */
  1818. X
  1819. X%union {
  1820. X    int ival;
  1821. X    double dval;
  1822. X    char sval[MAX_TOK_LEN];
  1823. X    }
  1824. X
  1825. X/*
  1826. X * Reserved words
  1827. X */
  1828. X
  1829. X%token CLASS CREATURE NAMED HD D MOVE SPELL BREATH DEFENSE XP CCHAR SLEEP
  1830. X%token RADIUS SPEED ATTACK FOR AC LEVEL TREASURE SPECIAL OF IN
  1831. X
  1832. X/*
  1833. X * Entities
  1834. X */
  1835. X
  1836. X%token <sval> IDENTIFIER    /* identifier, not a keyword            */
  1837. X%token <dval> FLOAT_LIT        /* floating-pt literal                */
  1838. X%token <ival> INT_LIT        /* integer literal                */
  1839. X%token <sval> STRING_LIT    /* string literal                */
  1840. X%token <ival> BOOL_LIT        /* boolean literal                */
  1841. X
  1842. X/*
  1843. X * ASCII chars are their own tokens
  1844. X */
  1845. X
  1846. X%start    creatures
  1847. X
  1848. X
  1849. X/*
  1850. X * THE PARSER
  1851. X */
  1852. X
  1853. X%%
  1854. X
  1855. Xcreatures    :    class_def ';' creatures
  1856. X        |    creature_def ';' creatures
  1857. X        |    /* empty */
  1858. X        ;
  1859. X
  1860. Xclass_def    :    CLASS IDENTIFIER parent_class '{' features '}'
  1861. X                { PutClassTemplate($<sval>2, &tmpTemplate); }
  1862. X        ;
  1863. X
  1864. Xparent_class    :    ':' IDENTIFIER
  1865. X                { tmpTemplate = GetClassTemplate($<sval>2);
  1866. X                  creatureAttacks = 0; }
  1867. X        |    /* empty */
  1868. X                { tmpTemplate = blankTemplate;
  1869. X                  creatureAttacks = 0; }
  1870. X        ;
  1871. X
  1872. Xcreature_def    :    CREATURE STRING_LIT parent_class 
  1873. X            '{' features '}'
  1874. X                { tmpTemplate.val.name = 
  1875. X                    (char *) malloc(strlen($<sval>2) + 1);
  1876. X                  strcpy(tmpTemplate.val.name, $<sval>2);
  1877. X                  PutCreature($<sval>2, &tmpTemplate);
  1878. X                }
  1879. X        ;
  1880. X
  1881. Xfeatures    :    feature ';' features
  1882. X        |    /* empty */
  1883. X        ;
  1884. X
  1885. Xfeature        :    LEVEL ':' INT_LIT
  1886. X                { tmpTemplate.val.level = $<ival>3;
  1887. X                  tmpTemplate.def.level = TRUE; }
  1888. X        |    HD ':' INT_LIT D INT_LIT
  1889. X                { tmpTemplate.val.hd[0] = $<ival>3;
  1890. X                  tmpTemplate.val.hd[1] = $<ival>5;
  1891. X                  tmpTemplate.def.hd = TRUE; }
  1892. X        |    XP ':' INT_LIT
  1893. X                { tmpTemplate.val.mexp = $<ival>3;
  1894. X                  tmpTemplate.def.mexp = TRUE; }
  1895. X        |    CCHAR ':' STRING_LIT
  1896. X                { tmpTemplate.val.cchar = $<sval>3[0];
  1897. X                  tmpTemplate.def.cchar = TRUE; }
  1898. X        |    AC ':' INT_LIT
  1899. X                { tmpTemplate.val.ac = $<ival>3;
  1900. X                  tmpTemplate.def.ac = TRUE; }
  1901. X        |    SLEEP ':' INT_LIT
  1902. X                { tmpTemplate.val.sleep = $<ival>3;
  1903. X                  tmpTemplate.def.sleep = TRUE; }
  1904. X        |    RADIUS ':' INT_LIT
  1905. X                { tmpTemplate.val.aaf = $<ival>3;
  1906. X                  tmpTemplate.def.aaf = TRUE; }
  1907. X        |    SPEED ':' INT_LIT
  1908. X                { tmpTemplate.val.speed = $<ival>3 + 10;
  1909. X                  tmpTemplate.def.speed = TRUE; }
  1910. X        |    ATTACK ':' attacks
  1911. X        |    MOVE ':' moves
  1912. X        |    SPELL ':' spells
  1913. X        |    SPELL INT_LIT '%' ':' spells
  1914. X                { float chance = 100.0 / $<ival>2;
  1915. X                  if (chance > 15.0)
  1916. X                      chance = 0.0;
  1917. X                  if (chance < 0.0)
  1918. X                      chance = 0.0;
  1919. X                  tmpTemplate.val.spells &= ~0xf;
  1920. X                  tmpTemplate.val.spells |=
  1921. X                      (int) ceil(chance);
  1922. X                  tmpTemplate.def.spell = TRUE; }
  1923. X        |    BREATH ':' breaths
  1924. X        |    BREATH INT_LIT '%' ':' breaths
  1925. X                { float chance = 100.0 / $<ival>2;
  1926. X                  if (chance > 15.0)
  1927. X                      chance = 0.0;
  1928. X                  if (chance < 0.0)
  1929. X                      chance = 0.0;
  1930. X                  tmpTemplate.val.spells &= ~0xf;
  1931. X                  tmpTemplate.val.spells |=
  1932. X                      (int) ceil(chance);
  1933. X                  tmpTemplate.def.spell = TRUE; }
  1934. X        |    DEFENSE ':' defenses
  1935. X        |    TREASURE ':' carries
  1936. X        |    SPECIAL ':' specials
  1937. X        ;
  1938. X
  1939. Xattacks        :    attack more_attacks
  1940. X        ;
  1941. X
  1942. Xattack        :    IDENTIFIER FOR INT_LIT D INT_LIT OF IDENTIFIER
  1943. X                { AddAttack($<sval>1, $<ival>3,
  1944. X                        $<ival>5, $<sval>7); }
  1945. X        ;
  1946. X
  1947. Xmore_attacks    :    ',' attack more_attacks
  1948. X        |    /* empty */
  1949. X        ;
  1950. X
  1951. Xmoves        :    move more_moves
  1952. X        ;
  1953. X
  1954. Xmove        :    IDENTIFIER { AddMove($<sval>1); }
  1955. X        |    '~' IDENTIFIER { NegMove($<sval>2); }
  1956. X        ;
  1957. X
  1958. Xmore_moves    :    ',' move more_moves
  1959. X        |    /* empty */
  1960. X        ;
  1961. X
  1962. Xspells        :    spell more_spells
  1963. X        |    /* empty */
  1964. X        ;
  1965. X
  1966. Xspell        :    IDENTIFIER { AddSpell($<sval>1); }
  1967. X        |    '~' IDENTIFIER { NegSpell($<sval>2); }
  1968. X        ;
  1969. X
  1970. Xmore_spells    :    ',' spell more_spells
  1971. X        |    /* empty */
  1972. X        ;
  1973. X
  1974. Xbreaths        :    breath more_breaths
  1975. X        ;
  1976. X
  1977. Xbreath        :    IDENTIFIER { AddBreath($<sval>1); }
  1978. X        |    '~' IDENTIFIER { NegBreath($<sval>2); }
  1979. X        ;
  1980. X
  1981. Xmore_breaths    :    ',' breath more_breaths
  1982. X        |    /* empty */
  1983. X        ;
  1984. X
  1985. Xdefenses    :    defense more_defenses
  1986. X        ;
  1987. X
  1988. Xdefense        :    IDENTIFIER { AddDefense($<sval>1); }
  1989. X        |    '~' IDENTIFIER { NegDefense($<sval>2); }
  1990. X        ;
  1991. X
  1992. Xmore_defenses    :    ',' defense more_defenses
  1993. X        |    /* empty */
  1994. X        ;
  1995. X
  1996. Xcarries        :    carry more_carries
  1997. X        ;
  1998. X
  1999. Xcarry        :    IDENTIFIER { AddTreasure($<sval>1); }
  2000. X        |    '~' IDENTIFIER { NegTreasure($<sval>2); }
  2001. X        ;
  2002. X
  2003. Xmore_carries    :    ',' carry more_carries
  2004. X        |    /* empty */
  2005. X        ;
  2006. X
  2007. Xspecials    :    special more_specials
  2008. X        ;
  2009. X
  2010. Xspecial        :    IDENTIFIER { AddSpecial($<sval>1); }
  2011. X        |    '~' IDENTIFIER { NegSpecial($<sval>2); }
  2012. X        ;
  2013. X
  2014. Xmore_specials    :    ',' special more_specials
  2015. X        |    /* empty */
  2016. X        ;
  2017. X
  2018. X        
  2019. X%%
  2020. X
  2021. Xstatic symInit_t keywordInit[] = {
  2022. X    { "class", CLASS },
  2023. X    { "creature", CREATURE },
  2024. X    { "named", NAMED },
  2025. X    { "hd", HD },
  2026. X    { "d", D },
  2027. X    { "move", MOVE },
  2028. X    { "spell", SPELL },
  2029. X    { "breath", BREATH },
  2030. X    { "defense", DEFENSE },
  2031. X    { "xp", XP },
  2032. X    { "cchar", CCHAR },
  2033. X    { "sleep", SLEEP },
  2034. X    { "radius", RADIUS },
  2035. X    { "speed", SPEED },
  2036. X    { "attack", ATTACK },
  2037. X    { "for", FOR },
  2038. X    { "ac", AC },
  2039. X    { "level", LEVEL },
  2040. X    { "treasure", TREASURE },    
  2041. X    { "special", SPECIAL },
  2042. X    { "of", OF },
  2043. X    { "in", IN },
  2044. X    { NULL, 0 }
  2045. X};
  2046. X
  2047. X
  2048. X
  2049. X/*
  2050. X * MyFGetC--
  2051. X *    fgetc with support for comments
  2052. X *
  2053. X *    # is the comment character.  comment lasts till end of line.
  2054. X * Spews out an extra char of whitespace at EOF since something seems to
  2055. X * need it.  I'll figure this out eventually...
  2056. X */
  2057. Xstatic int MyFGetC(input_F)
  2058. XFILE *input_F;
  2059. X{
  2060. X    static int atEof = FALSE;
  2061. X    while (!*inputBufp || (*inputBufp == '#')) {
  2062. X    fgets(inputBuf, INPUT_BUF_SIZE, input_F);
  2063. X        if (feof(input_F))
  2064. X        return EOF;
  2065. X    lineNo++;
  2066. X    inputBufp = inputBuf;
  2067. X    }
  2068. X    return *inputBufp++;
  2069. X}
  2070. X
  2071. X
  2072. X
  2073. X/*
  2074. X * Advance--
  2075. X *    Advance to the next token in the input stream and set tokStr, 
  2076. X * tokType, tokVal as appropriate.
  2077. X *
  2078. X *    On error, tokType is set to a negative value.
  2079. X */
  2080. Xstatic void Advance(input_F)
  2081. XFILE *input_F;
  2082. X{
  2083. X
  2084. X    register char
  2085. X        *tok = tokStr;    /* accumulating token string            */
  2086. X    register int
  2087. X        len = 0;        /* length of current token            */
  2088. X    static int c = 32;        /* current character; ' ' is harmless init  */
  2089. X
  2090. X
  2091. X    /*
  2092. X     * Skip whitespace in the stream
  2093. X     */
  2094. X    while ((c != EOF) && isspace(c))
  2095. X    c = MyFGetC(input_F);
  2096. X
  2097. X    /*
  2098. X     * At end of file?
  2099. X     */
  2100. X    if (c == EOF) {
  2101. X    tokType = EOF;
  2102. X    strcpy(tokStr, "[EOF]");
  2103. X    return;
  2104. X    }
  2105. X
  2106. X    /*
  2107. X     * Recognize a number [+|-][dddd][.][dddd][{e|E}[+|-]dddd]
  2108. X     */
  2109. X    if (isdigit(c) || (c == '.') || (c == '+') || (c == '-')) {
  2110. X
  2111. X    register int 
  2112. X        decPt = FALSE,        /* seen a decimal point yet?    */
  2113. X        hasExp = FALSE;        /* has an exponent?            */
  2114. X
  2115. X    if ((c == '-') || (c == '+')) {
  2116. X        *tok++ = c;
  2117. X        c = MyFGetC(input_F);
  2118. X    }
  2119. X
  2120. X    while ((len < MAX_TOK_LEN - 1) && (isdigit(c) || (c == '.'))) {
  2121. X        if (c == '.') {
  2122. X        if (decPt)
  2123. X            break;
  2124. X        else
  2125. X            decPt = TRUE;
  2126. X        }
  2127. X
  2128. X        *tok++ = c;
  2129. X        c = MyFGetC(input_F);
  2130. X        len++;
  2131. X    }
  2132. X
  2133. X    if ((c == 'e') || (c == 'E')) {
  2134. X        hasExp = TRUE;
  2135. X        *tok++ = c;
  2136. X        c = MyFGetC(input_F);
  2137. X        len++;
  2138. X
  2139. X        if ((c == '-') || (c == '+')) {
  2140. X        *tok++ = c;
  2141. X        c = MyFGetC(input_F);
  2142. X        len++;
  2143. X        }
  2144. X
  2145. X        while ((len < MAX_TOK_LEN - 1) && isdigit(c)) {
  2146. X        *tok++ = c;
  2147. X        c = MyFGetC(input_F);
  2148. X        len++;
  2149. X        }
  2150. X    }
  2151. X
  2152. X    *tok = 0;
  2153. X
  2154. X    if (decPt || hasExp) {
  2155. X        tokType = FLOAT_LIT;
  2156. X        yylval.dval = atof(tokStr);
  2157. X    } else {
  2158. X        tokType = INT_LIT;
  2159. X        yylval.ival = atoi(tokStr);
  2160. X    }
  2161. X
  2162. X    return;
  2163. X
  2164. X    }
  2165. X
  2166. X    /*
  2167. X     * Recognize a quoted string
  2168. X     */
  2169. X    if (c == '\"') {
  2170. X
  2171. X    c = MyFGetC(input_F);
  2172. X
  2173. X    while ((len < MAX_TOK_LEN - 1) &&
  2174. X                (c != EOF) && (c != '\n') && (c != '\"')) {
  2175. X        *tok++ = c;
  2176. X        c = MyFGetC(input_F);
  2177. X    }
  2178. X
  2179. X    *tok = 0;
  2180. X
  2181. X    c = MyFGetC(input_F);
  2182. X
  2183. X    tokType = STRING_LIT;
  2184. X    strncpy(yylval.sval, tokStr, MAX_TOK_LEN - 1);
  2185. X    yylval.sval[MAX_TOK_LEN - 1] = 0;
  2186. X
  2187. X    return;
  2188. X
  2189. X    }
  2190. X
  2191. X    /*
  2192. X     * Recognize an identifier and try to match it with a keyword.
  2193. X     * Identifiers begin with a letter and continue in letters and/or
  2194. X     * digits.  Convert it to lowercase.
  2195. X     */
  2196. X    if (isalpha(c) || (c == '_') || (c == '$')) {
  2197. X
  2198. X        if (isupper(c))
  2199. X      c = tolower(c);
  2200. X        *tok++ = c;
  2201. X    c = MyFGetC(input_F);
  2202. X    len++;
  2203. X
  2204. X    while ((len < MAX_TOK_LEN - 1) && (isalpha(c) || isdigit(c) ||
  2205. X                        (c == '_') || (c == '$'))) {
  2206. X        if (isupper(c))
  2207. X          c = tolower(c);
  2208. X        *tok++ = c;
  2209. X        c = MyFGetC(input_F);
  2210. X        len++;
  2211. X    }
  2212. X
  2213. X    *tok = 0;
  2214. X
  2215. X    /*
  2216. X     * We've got the identifier; see if it matches any keywords.
  2217. X     */
  2218. X
  2219. X    {
  2220. X        generic_t gval;
  2221. X        int type;
  2222. X        if (St_GetSym(keywordT_P, tokStr, &type, &gval) ==
  2223. X                                ST_SYM_FOUND) {
  2224. X            tokType = gval.i;
  2225. X                strncpy(yylval.sval, tokStr, MAX_TOK_LEN - 1);
  2226. X            yylval.sval[MAX_TOK_LEN - 1] = 0;
  2227. X        } else if (!strcmp(tokStr, "true")) {
  2228. X            tokType = BOOL_LIT;
  2229. X            yylval.ival = 1;
  2230. X        } else if (!strcmp(tokStr, "false")) {
  2231. X            tokType = BOOL_LIT;
  2232. X            yylval.ival = 0;
  2233. X        } else {
  2234. X            tokType = IDENTIFIER;
  2235. X            strncpy(yylval.sval, tokStr, MAX_TOK_LEN - 1);
  2236. X            yylval.sval[MAX_TOK_LEN - 1] = 0;
  2237. X        }
  2238. X    }
  2239. X
  2240. X    return;
  2241. X
  2242. X    }
  2243. X
  2244. X    /*
  2245. X     * Recognize punctuation
  2246. X     */
  2247. X
  2248. X    tokType = c;
  2249. X    *tok++ = c;
  2250. X    *tok = 0;
  2251. X    c = MyFGetC(input_F);
  2252. X    return;
  2253. X
  2254. X}
  2255. X
  2256. Xvoid ErrMsg(s)
  2257. Xchar *s;
  2258. X{    
  2259. X    int i;
  2260. X
  2261. X    fprintf(stderr, "Error: %s at line %d\n", s, lineNo);
  2262. X    fprintf(stderr, "%s", inputBuf);
  2263. X    for (i = 0; i < inputBufp - inputBuf; i++) {
  2264. X        fputc((inputBuf[i] == '\t' ? '\t' : ' '), stderr);
  2265. X    }
  2266. X    fprintf(stderr, "^ before here\n\n");
  2267. X}
  2268. X
  2269. Xint yyerror(s)
  2270. Xchar *s;
  2271. X{
  2272. X    ErrMsg(s);
  2273. X}
  2274. X
  2275. X
  2276. Xint yylex()
  2277. X{
  2278. X    Advance(input_F);
  2279. X    return(tokType);
  2280. X}
  2281. X
  2282. Xvoid AddSpell(s)
  2283. Xchar *s;
  2284. X{
  2285. X    generic_t gval;
  2286. X    int type;
  2287. X    char s1[256];
  2288. X    
  2289. X    if (St_GetSym(spellT_P, s, &type, &gval) != ST_SYM_FOUND) {
  2290. X        sprintf(s1, "unknown spell '%s'", s);
  2291. X        ErrMsg(s1);
  2292. X    } else {
  2293. X        tmpTemplate.val.spells |= (1 << gval.i);
  2294. X        tmpTemplate.def.spell = TRUE;
  2295. X    }
  2296. X}
  2297. X    
  2298. X
  2299. Xvoid NegSpell(s)
  2300. Xchar *s;
  2301. X{
  2302. X    generic_t gval;
  2303. X    int type;
  2304. X    char s1[256];
  2305. X    
  2306. X    if (St_GetSym(spellT_P, s, &type, &gval) != ST_SYM_FOUND) {
  2307. X        sprintf(s1, "unknown spell '%s'", s);
  2308. X        ErrMsg(s1);
  2309. X    } else {
  2310. X        tmpTemplate.val.spells &= ~(1 << gval.i);
  2311. X        tmpTemplate.def.spell = TRUE;
  2312. X    }
  2313. X}
  2314. X    
  2315. X
  2316. Xvoid AddBreath(s)
  2317. Xchar *s;
  2318. X{
  2319. X    generic_t gval;
  2320. X    int type;
  2321. X    char s1[256];
  2322. X    
  2323. X    if (St_GetSym(breathT_P, s, &type, &gval) != ST_SYM_FOUND) {
  2324. X        sprintf(s1, "unknown breath '%s'", s);
  2325. X        ErrMsg(s1);
  2326. X    } else {
  2327. X        tmpTemplate.val.spells |= (1 << gval.i);
  2328. X        tmpTemplate.def.breath = TRUE;
  2329. X    }
  2330. X}
  2331. X    
  2332. X
  2333. Xvoid NegBreath(s)
  2334. Xchar *s;
  2335. X{
  2336. X    generic_t gval;
  2337. X    int type;
  2338. X    char s1[256];
  2339. X    
  2340. X    if (St_GetSym(breathT_P, s, &type, &gval) != ST_SYM_FOUND) {
  2341. X        sprintf(s1, "unknown breath '%s'", s);
  2342. X        ErrMsg(s1);
  2343. X    } else {
  2344. X        tmpTemplate.val.spells &= ~(1 << gval.i);
  2345. X        tmpTemplate.def.breath = TRUE;
  2346. X    }
  2347. X}
  2348. X    
  2349. X
  2350. Xvoid AddSpecial(s)
  2351. Xchar *s;
  2352. X{
  2353. X    generic_t gval;
  2354. X    int type;
  2355. X    char s1[256];
  2356. X    
  2357. X    if (St_GetSym(specialT_P, s, &type, &gval) != ST_SYM_FOUND) {
  2358. X        sprintf(s1, "unknown special '%s'", s);
  2359. X        ErrMsg(s1);
  2360. X    } else {
  2361. X        tmpTemplate.val.cmove |= (1 << gval.i);
  2362. X        tmpTemplate.def.special = TRUE;
  2363. X    }
  2364. X}
  2365. X    
  2366. X
  2367. Xvoid NegSpecial(s)
  2368. Xchar *s;
  2369. X{
  2370. X    generic_t gval;
  2371. X    int type;
  2372. X    char s1[256];
  2373. X    
  2374. X    if (St_GetSym(specialT_P, s, &type, &gval) != ST_SYM_FOUND) {
  2375. X        sprintf(s1, "unknown special '%s'", s);
  2376. X        ErrMsg(s1);
  2377. X    } else {
  2378. X        tmpTemplate.val.cmove &= ~(1 << gval.i);
  2379. X        tmpTemplate.def.special = TRUE;
  2380. X    }
  2381. X}
  2382. X    
  2383. X
  2384. Xvoid AddMove(s)
  2385. Xchar *s;
  2386. X{
  2387. X    generic_t gval;
  2388. X    int type;
  2389. X    char s1[256];
  2390. X    
  2391. X    if (St_GetSym(moveT_P, s, &type, &gval) != ST_SYM_FOUND) {
  2392. X        sprintf(s1, "unknown move '%s'", s);
  2393. X        ErrMsg(s1);
  2394. X    } else {
  2395. X        tmpTemplate.val.cmove |= (1 << gval.i);
  2396. X        tmpTemplate.def.move = TRUE;
  2397. X    }
  2398. X}
  2399. X    
  2400. X
  2401. Xvoid NegMove(s)
  2402. Xchar *s;
  2403. X{
  2404. X    generic_t gval;
  2405. X    int type;
  2406. X    char s1[256];
  2407. X    
  2408. X    if (St_GetSym(moveT_P, s, &type, &gval) != ST_SYM_FOUND) {
  2409. X        sprintf(s1, "unknown move '%s'", s);
  2410. X        ErrMsg(s1);
  2411. X    } else {
  2412. X        tmpTemplate.val.cmove &= ~(1 << gval.i);
  2413. X        tmpTemplate.def.move = TRUE;
  2414. X    }
  2415. X}
  2416. X    
  2417. X
  2418. Xvoid AddTreasure(s)
  2419. Xchar *s;
  2420. X{
  2421. X    generic_t gval;
  2422. X    int type;
  2423. X    char s1[256];
  2424. X    
  2425. X    if (St_GetSym(treasureT_P, s, &type, &gval) != ST_SYM_FOUND) {
  2426. X        sprintf(s1, "unknown treasure '%s'", s);
  2427. X        ErrMsg(s1);
  2428. X    } else {
  2429. X        tmpTemplate.val.cmove |= (1 << gval.i);
  2430. X        tmpTemplate.def.treasure = TRUE;
  2431. X    }
  2432. X}
  2433. X    
  2434. X
  2435. Xvoid NegTreasure(s)
  2436. Xchar *s;
  2437. X{
  2438. X    generic_t gval;
  2439. X    int type;
  2440. X    char s1[256];
  2441. X    
  2442. X    if (St_GetSym(treasureT_P, s, &type, &gval) != ST_SYM_FOUND) {
  2443. X        sprintf(s1, "unknown treasure '%s'", s);
  2444. X        ErrMsg(s1);
  2445. X    } else {
  2446. X        tmpTemplate.val.cmove &= ~(1 << gval.i);
  2447. X        tmpTemplate.def.treasure = TRUE;
  2448. X    }
  2449. X}
  2450. X    
  2451. X
  2452. Xvoid AddDefense(s)
  2453. Xchar *s;
  2454. X{
  2455. X    generic_t gval;
  2456. X    int type;
  2457. X    char s1[256];
  2458. X    
  2459. X    if (St_GetSym(defenseT_P, s, &type, &gval) != ST_SYM_FOUND) {
  2460. X        sprintf(s1, "unknown defense '%s'", s);
  2461. X        ErrMsg(s1);
  2462. X    } else {
  2463. X        tmpTemplate.val.cdefense |= (1 << gval.i);
  2464. X        tmpTemplate.def.defense = TRUE;
  2465. X    }
  2466. X}
  2467. X    
  2468. X
  2469. Xvoid NegDefense(s)
  2470. Xchar *s;
  2471. X{
  2472. X    generic_t gval;
  2473. X    int type;
  2474. X    char s1[256];
  2475. X    
  2476. X    if (St_GetSym(defenseT_P, s, &type, &gval) != ST_SYM_FOUND) {
  2477. X        sprintf(s1, "unknown defense '%s'", s);
  2478. X        ErrMsg(s1);
  2479. X    } else {
  2480. X        tmpTemplate.val.cdefense &= ~(1 << gval.i);
  2481. X        tmpTemplate.def.defense = TRUE;
  2482. X    }
  2483. X}
  2484. X    
  2485. X
  2486. Xint PutAttack(attack)
  2487. Xattack_t attack;
  2488. X{
  2489. X    register int i;
  2490. X
  2491. X    for (i = 0; i < attackCt; i++) {
  2492. X        if ((attack.type == attackList[i].type) &&
  2493. X            (attack.desc == attackList[i].desc) &&
  2494. X            (attack.dice == attackList[i].dice) &&
  2495. X            (attack.sides == attackList[i].sides)) {
  2496. X                return(i);
  2497. X        }
  2498. X    }
  2499. X
  2500. X    if (attackCt == MAX_ATTACK) {
  2501. X        fprintf(stderr, "fatal error: too many different attacks.\n");
  2502. X        fprintf(stderr, "increase MAX_ATTACK.\n");
  2503. X        exit(1);
  2504. X    }
  2505. X
  2506. X    attackList[attackCt].type = attack.type;
  2507. X    attackList[attackCt].desc = attack.desc;
  2508. X    attackList[attackCt].dice = attack.dice;
  2509. X    attackList[attackCt].sides = attack.sides;
  2510. X    
  2511. X    return attackCt++;
  2512. X}
  2513. X
  2514. Xvoid AddAttack(s1, dice, sides, s2)
  2515. Xchar *s1, *s2; 
  2516. Xint dice, sides; 
  2517. X{
  2518. X    generic_t gval;
  2519. X    int type, aDesc;
  2520. X    attack_t attack;
  2521. X    char s[256];
  2522. X    
  2523. X    if (St_GetSym(attackDescT_P, s1, &type, &gval) != ST_SYM_FOUND) {
  2524. X        sprintf(s, "unknown attack description '%s'", s1);
  2525. X        ErrMsg(s);
  2526. X        return;
  2527. X    } else {
  2528. X        aDesc = gval.i;
  2529. X    }
  2530. X
  2531. X    if (St_GetSym(attackTypeT_P, s2, &type, &gval) != ST_SYM_FOUND) {
  2532. X        sprintf(s, "unknown attack type '%s'", s2);
  2533. X        ErrMsg(s);
  2534. X    } else {
  2535. X        if (creatureAttacks > 3) {
  2536. X            sprintf(s, "creature limited to 4 attacks");
  2537. X            ErrMsg(s);
  2538. X            return;
  2539. X        }            
  2540. X        attack.type = gval.i;
  2541. X        attack.dice = dice;
  2542. X        attack.desc = aDesc;
  2543. X        attack.sides = sides;
  2544. X        tmpTemplate.val.damage[creatureAttacks++] = 
  2545. X                        PutAttack(attack);
  2546. X        tmpTemplate.def.damage = TRUE;
  2547. X    }
  2548. X}
  2549. X
  2550. Xst_Table_Pt InitTable(name, init)
  2551. Xchar *name;
  2552. XsymInit_t *init;
  2553. X{
  2554. X    int i;
  2555. X    st_Table_Pt table_P;
  2556. X    generic_t gval;
  2557. X
  2558. X    table_P = St_NewTable(name, 20);
  2559. X    for (i = 0; init[i].name; i++) {
  2560. X        gval.i = init[i].val;
  2561. X        St_DefSym(table_P, init[i].name, GEN_TYPE_INT, gval);
  2562. X    }
  2563. X
  2564. X    return table_P;
  2565. X}
  2566. X    
  2567. X
  2568. Xvoid InitTables()
  2569. X{
  2570. X    int i;
  2571. X    generic_t gval;
  2572. X
  2573. X    keywordT_P = InitTable("keyword", keywordInit);
  2574. X    defenseT_P = InitTable("defense", defenseInit);
  2575. X    spellT_P = InitTable("spell", spellInit);
  2576. X    moveT_P = InitTable("move", moveInit);
  2577. X    specialT_P = InitTable("special", specialInit);
  2578. X    breathT_P = InitTable("breath", breathInit);
  2579. X    treasureT_P = InitTable("treasure", treasureInit);
  2580. X    attackTypeT_P = InitTable("attackType", attackTypeInit);
  2581. X    attackDescT_P = InitTable("attackDesc", attackDescInit);
  2582. X    
  2583. X    classT_P = St_NewTable("class", 40);
  2584. X    creatureT_P = St_NewTable("creature", 200);
  2585. X}
  2586. X
  2587. Xvoid WriteCreature(tmpl_P)
  2588. Xtemplate_t *tmpl_P;
  2589. X{
  2590. X    char s[256];
  2591. X    strcpy(s, "\"");
  2592. X    strcat(s, tmpl_P->val.name);
  2593. X    strcat(s, "\"");
  2594. X    printf("{%-28s, 0x%08x,0x%06x,0x%04x,%5d,%3d,\n",
  2595. X        s, tmpl_P->val.cmove, tmpl_P->val.spells,
  2596. X        tmpl_P->val.cdefense, tmpl_P->val.mexp, tmpl_P->val.sleep);
  2597. X    printf(" %2d, %3d, %2d, '%c', {%3d,%2d}, {%3d,%3d,%3d,%3d}, %3d},\n",
  2598. X        tmpl_P->val.aaf, tmpl_P->val.ac, tmpl_P->val.speed, 
  2599. X        tmpl_P->val.cchar,
  2600. X        tmpl_P->val.hd[0], tmpl_P->val.hd[1], 
  2601. X        tmpl_P->val.damage[0], tmpl_P->val.damage[1], 
  2602. X        tmpl_P->val.damage[2], tmpl_P->val.damage[3],
  2603. X        tmpl_P->val.level);
  2604. X}
  2605. X
  2606. Xvoid WriteCreatures()
  2607. X{
  2608. X    char **s_A, **sp;
  2609. X    int level, type;
  2610. X    generic_t gval;
  2611. X    
  2612. X    s_A = St_SListTable(creatureT_P);
  2613. X    
  2614. X    printf("creature_type c_list[MAX_CREATURES] = {\n");
  2615. X    
  2616. X    for (level = 0; level <= maxCreatureLevel; level++) {
  2617. X        for (sp = s_A; *sp; sp++) {
  2618. X        if (St_GetSym(creatureT_P, *sp, &type, &gval) !=
  2619. X                            ST_SYM_FOUND) {
  2620. X            fprintf(stderr, "internal err. in WriteCreatures\n");
  2621. X            exit(1);
  2622. X        }
  2623. X        if ((*(template_t *) gval.v).val.level == level) {
  2624. X            WriteCreature((template_t *) gval.v);
  2625. X        }
  2626. X       }
  2627. X    }
  2628. X    
  2629. X    printf("};\n\n");
  2630. X    
  2631. X    St_SListTable(NULL);
  2632. X}
  2633. X
  2634. Xvoid PutClassTemplate(s, tmpl_P)
  2635. Xchar *s; 
  2636. Xtemplate_t *tmpl_P;
  2637. X{
  2638. X    generic_t gval;
  2639. X    char s1[256];
  2640. X    
  2641. X    gval.v = malloc(sizeof(template_t));
  2642. X    *(template_t *) gval.v = *tmpl_P;
  2643. X
  2644. X    if (St_DefSym(classT_P, s, GEN_TYPE_TMPL, gval) == ST_SYM_FOUND) {
  2645. X        sprintf(s1, "attempt to redefine class '%s'", s);
  2646. X        ErrMsg(s1);
  2647. X        free(gval.v);
  2648. X        return;
  2649. X    }
  2650. X}    
  2651. X    
  2652. X
  2653. Xtemplate_t GetClassTemplate(s)
  2654. Xchar *s;
  2655. X{
  2656. X    generic_t gval;
  2657. X    int type;
  2658. X    char s1[256];
  2659. X    
  2660. X    if (St_GetSym(classT_P, s, &type, &gval) != ST_SYM_FOUND) {
  2661. X        sprintf(s1, "class '%s' undefined\n", s);
  2662. X        ErrMsg(s1);
  2663. X        return blankTemplate;
  2664. X    } else {
  2665. X        return *(template_t *) gval.v;
  2666. X    }
  2667. X}
  2668. X
  2669. X
  2670. X
  2671. X
  2672. Xvoid NotDefined(name, s)
  2673. Xchar *name, *s;
  2674. X{
  2675. X    printf("Warning: %s not defined for \"%s\", line %d\n",
  2676. X        s, name, lineNo);
  2677. X}
  2678. X
  2679. X
  2680. Xvoid PutCreature(s, tmpl_P)
  2681. Xchar *s; 
  2682. Xtemplate_t *tmpl_P;
  2683. X{
  2684. X    generic_t gval;
  2685. X    char s1[256];
  2686. X    
  2687. X    gval.v = malloc(sizeof(template_t));
  2688. X    *(template_t *) gval.v = *tmpl_P;
  2689. X
  2690. X    if (!tmpl_P->def.move)
  2691. X        NotDefined(tmpl_P->val.name, "MOVE");
  2692. X    if (!tmpl_P->def.treasure)
  2693. X        NotDefined(tmpl_P->val.name, "TREASURE");
  2694. X    if (!tmpl_P->def.defense)
  2695. X        NotDefined(tmpl_P->val.name, "DEFENSE");
  2696. X    if (!tmpl_P->def.mexp)
  2697. X        NotDefined(tmpl_P->val.name, "XP");
  2698. X    if (!tmpl_P->def.sleep)
  2699. X        NotDefined(tmpl_P->val.name, "SLEEP");
  2700. X    if (!tmpl_P->def.aaf)
  2701. X        NotDefined(tmpl_P->val.name, "RADIUS");
  2702. X    if (!tmpl_P->def.ac)
  2703. X        NotDefined(tmpl_P->val.name, "AC");
  2704. X    if (!tmpl_P->def.speed)
  2705. X        NotDefined(tmpl_P->val.name, "SPEED");
  2706. X    if (!tmpl_P->def.cchar)
  2707. X        NotDefined(tmpl_P->val.name, "CCHAR");
  2708. X    if (!tmpl_P->def.hd)
  2709. X        NotDefined(tmpl_P->val.name, "HD");
  2710. X    if (!tmpl_P->def.damage)
  2711. X        NotDefined(tmpl_P->val.name, "ATTACK");
  2712. X    if (!tmpl_P->def.level)
  2713. X        NotDefined(tmpl_P->val.name, "LEVEL");
  2714. X        
  2715. X    if (St_DefSym(creatureT_P, s, GEN_TYPE_TMPL, gval) == ST_SYM_FOUND) {
  2716. X        sprintf(s1, "attempt to redefine creature '%s'\n", s);
  2717. X        ErrMsg(s1);
  2718. X        free(gval.v);
  2719. X        return;
  2720. X    }
  2721. X
  2722. X    if (tmpl_P->val.level > maxCreatureLevel)
  2723. X        maxCreatureLevel = tmpl_P->val.level;
  2724. X
  2725. X}    
  2726. X    
  2727. Xvoid WriteAttacks()
  2728. X{
  2729. X    int i;
  2730. X    
  2731. X    printf("struct m_attack_type monster_attacks[N_MONS_ATTS] = {\n");
  2732. X    for (i = 0; i < attackCt; i++) {
  2733. X        printf("/* %3d */ { %2d, %2d, %2d, %2d },\n",
  2734. X            i, attackList[i].type, attackList[i].desc,
  2735. X            attackList[i].dice, attackList[i].sides);
  2736. X    };
  2737. X    printf("};\n");
  2738. X}
  2739. X
  2740. Xvoid WriteConstants()
  2741. X{
  2742. X  printf("/* These values should match the values defined in constant.h. */");
  2743. X  printf("\n#define MAX_CREATURES\t%d\n", St_TableSize(creatureT_P));
  2744. X  printf("#define N_MON_ATTS\t%d\n\n", attackCt);
  2745. X}
  2746. X
  2747. Xvoid WriteMonsterHdr()
  2748. X{
  2749. X  printf("/* The following code belongs in the file monster.c. */\n\n");
  2750. X  printf("/* The following data was generated by the program in util/mc. */\n\n");
  2751. X}
  2752. X
  2753. Xmain(argc, argv)
  2754. Xint argc;
  2755. Xchar *argv[];
  2756. X{
  2757. X    char inputFilename[256];
  2758. X
  2759. X    InitTables();
  2760. X
  2761. X    if (argc > 1) {
  2762. X        strncpy(inputFilename, argv[1], 255);
  2763. X        inputFilename[255] = 0;
  2764. X    } else {
  2765. X        fprintf(stderr, "input file: ");
  2766. X        scanf("%255s", inputFilename);
  2767. X    }
  2768. X
  2769. X    input_F = fopen(inputFilename, "r");
  2770. X    if (!input_F) {
  2771. X        printf("Error: couldn't open file.\n");
  2772. X        exit(1);
  2773. X    }
  2774. X
  2775. X    if (yyparse()) {
  2776. X        printf("Errors prevent continuation.\n");
  2777. X        exit(1);
  2778. X    }
  2779. X    
  2780. X    WriteConstants();
  2781. X    WriteMonsterHdr();
  2782. X    WriteCreatures();
  2783. X    WriteAttacks();
  2784. X}
  2785. END_OF_FILE
  2786. if test 26718 -ne `wc -c <'util/mc/creature.y'`; then
  2787.     echo shar: \"'util/mc/creature.y'\" unpacked with wrong size!
  2788. fi
  2789. # end of 'util/mc/creature.y'
  2790. fi
  2791. echo shar: End of archive 20 \(of 31\).
  2792. cp /dev/null ark20isdone
  2793. MISSING=""
  2794. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ; do
  2795.     if test ! -f ark${I}isdone ; then
  2796.     MISSING="${MISSING} ${I}"
  2797.     fi
  2798. done
  2799. if test "${MISSING}" = "" ; then
  2800.     echo You have unpacked all 31 archives.
  2801.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2802. else
  2803.     echo You still need to unpack the following archives:
  2804.     echo "        " ${MISSING}
  2805. fi
  2806. ##  End of shell archive.
  2807. exit 0
  2808.