]> Zhao Yanbai Git Server - minix.git/commitdiff
Importing games/adventure
authorThomas Cort <tcort@minix3.org>
Sat, 15 Mar 2014 19:46:01 +0000 (15:46 -0400)
committerLionel Sambuc <lionel@minix3.org>
Mon, 28 Jul 2014 15:05:16 +0000 (17:05 +0200)
No Minix specific changes needed.

Change-Id: I6826d660c60a9e01676e21ef9b95d27e64a67aa5

21 files changed:
distrib/sets/lists/minix/mi
etc/mtree/NetBSD.dist.base
etc/profile
games/Makefile [new file with mode: 0644]
games/Makefile.inc [new file with mode: 0644]
games/adventure/Makefile [new file with mode: 0644]
games/adventure/adventure.6 [new file with mode: 0644]
games/adventure/crc.c [new file with mode: 0644]
games/adventure/done.c [new file with mode: 0644]
games/adventure/extern.h [new file with mode: 0644]
games/adventure/glorkz [new file with mode: 0644]
games/adventure/hdr.h [new file with mode: 0644]
games/adventure/init.c [new file with mode: 0644]
games/adventure/io.c [new file with mode: 0644]
games/adventure/main.c [new file with mode: 0644]
games/adventure/save.c [new file with mode: 0644]
games/adventure/setup.c [new file with mode: 0644]
games/adventure/subr.c [new file with mode: 0644]
games/adventure/vocab.c [new file with mode: 0644]
games/adventure/wizard.c [new file with mode: 0644]
releasetools/nbsd_ports

index 634bf0d2c52f4cef1c987ffbad7a4b663119598b..affc035a4fcdbea6ea9a29e99cd3b9fb9f00e530 100644 (file)
 ./usr/etc/daily                                minix-sys
 ./usr/etc/dhcptags.conf                        minix-sys
 ./usr/etc/rc                           minix-sys
+./usr/games                            minix-sys
+./usr/games/adventure                  minix-sys
+./usr/games/hide                       minix-sys
 ./usr/include                          minix-sys
 ./usr/include/aio.h                    minix-sys
 ./usr/include/a.out.h                  minix-sys
 ./usr/man/man5/usermgmt.conf.5                 minix-sys
 ./usr/man/man5/utmp.5                          minix-sys
 ./usr/man/man6                                 minix-sys
+./usr/man/man6/adventure.6                     minix-sys
 ./usr/man/man7                                 minix-sys
 ./usr/man/man7/ascii.7                         minix-sys
 ./usr/man/man7/atf.7                           minix-sys       atf
 ./usr/share/examples/lutok/hello.cpp   minix-sys       kyua
 ./usr/share/examples/lutok/interpreter.cpp     minix-sys       kyua
 ./usr/share/examples/lutok/raii.cpp    minix-sys       kyua
+./usr/share/games                      minix-sys
 ./usr/share/info                       minix-sys
 ./usr/share/info/as.info               minix-sys       binutils
 ./usr/share/info/bfd.info              minix-sys       binutils
index e1972712f108dce161d4635dbe7b7c14801071f9..344a55c21db56727febf02ac6a943320e259f91b 100644 (file)
@@ -42,6 +42,8 @@
 ./usr/benchmarks/unixbench/tmp
 ./usr/benchmarks/unixbench/testdir
 ./usr/benchmarks/unixbench/results
+./usr/games
+./usr/games/hide       gname=games mode=0750
 ./usr/include
 ./usr/include/arpa
 ./usr/include/compat
 ./usr/share/doc/psd
 ./usr/share/doc/psd/19.curses
 ./usr/share/info
+./usr/share/games
 ./usr/share/misc
 ./usr/share/mk
 ./usr/share/nvi
index 71c1a4e1b1626aa9ef3147aac27faa58ec0004ab..6daff7af1ae98b66bfe9e9c19721894cffcb17b9 100755 (executable)
@@ -4,7 +4,7 @@
 set -o emacs
 
 # Set the default path
-PATH=/usr/local/bin:/usr/pkg/bin:/usr/bin:/bin
+PATH=/usr/local/bin:/usr/pkg/bin:/usr/bin:/bin:/usr/games
 
 # Add ~/bin, iff it is present
 if [ -e ${HOME}/bin ]; then
diff --git a/games/Makefile b/games/Makefile
new file mode 100644 (file)
index 0000000..780ac92
--- /dev/null
@@ -0,0 +1,18 @@
+#      $NetBSD: Makefile,v 1.29 2013/11/12 17:46:20 mbalmer Exp $
+#      @(#)Makefile    8.3 (Berkeley) 7/24/94
+
+# Missing: dungeon warp
+# Moved: chess
+# Don't belong: xneko xroach
+
+.include <bsd.own.mk>
+
+SUBDIR=        adventure
+
+.if !defined(__MINIX)
+.if ${MKCXX} != "no"
+SUBDIR+=       dab 
+.endif
+.endif # !defined(__MINIX)
+
+.include <bsd.subdir.mk>
diff --git a/games/Makefile.inc b/games/Makefile.inc
new file mode 100644 (file)
index 0000000..5566c29
--- /dev/null
@@ -0,0 +1,23 @@
+#      $NetBSD: Makefile.inc,v 1.15 2012/06/19 05:46:08 dholland Exp $
+#      @(#)Makefile.inc        8.1 (Berkeley) 5/31/93
+
+MKHIDEGAME?=   no
+
+.if defined(HIDEGAME) && (${MKHIDEGAME} != no) && defined(PROG)
+BINDIR=                /usr/games/hide
+BINGRP=                games
+.if defined(SETGIDGAME)
+USE_FORT?=     yes
+BINMODE=       2550
+.else
+BINMODE=       550
+.endif
+SYMLINKS+=     dm /usr/games/${PROG}
+.else
+BINDIR=                /usr/games
+.if defined(SETGIDGAME)
+BINGRP=                games
+BINMODE=       2555
+.endif
+.endif
+WARNS?=                5
diff --git a/games/adventure/Makefile b/games/adventure/Makefile
new file mode 100644 (file)
index 0000000..8f3467e
--- /dev/null
@@ -0,0 +1,19 @@
+#      $NetBSD: Makefile,v 1.14 2013/02/16 16:30:28 jmcneill Exp $
+#      @(#)Makefile    8.1 (Berkeley) 6/12/93
+
+PROG=  adventure
+SRCS=  main.c init.c done.c save.c subr.c vocab.c wizard.c io.c data.c crc.c
+MAN=   adventure.6
+HIDEGAME=hidegame
+CLEANFILES+=mkdata setup.lo data.c
+
+data.c: glorkz mkdata
+       ${_MKTARGET_CREATE}
+       ./mkdata ${.CURDIR}/glorkz > data.c
+
+setup.lo: hdr.h
+mkdata: setup.lo
+       ${_MKTARGET_LINK}
+       ${HOST_LINK.c} -o ${.TARGET} ${.ALLSRC}
+
+.include <bsd.prog.mk>
diff --git a/games/adventure/adventure.6 b/games/adventure/adventure.6
new file mode 100644 (file)
index 0000000..cc8c7a8
--- /dev/null
@@ -0,0 +1,55 @@
+.\"    $NetBSD: adventure.6,v 1.4 2003/08/07 09:36:50 agc Exp $
+.\"
+.\" Copyright (c) 1991, 1993
+.\"    The Regents of the University of California.  All rights reserved.
+.\"
+.\" The game adventure was originally written in Fortran by Will Crowther
+.\" and Don Woods.  It was later translated to C and enhanced by Jim
+.\" Gillogly.  This code is derived from software contributed to Berkeley
+.\" by Jim Gillogly at The Rand Corporation.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"    @(#)adventure.6 8.1 (Berkeley) 5/31/93
+.\"
+.Dd May 31, 1993
+.Dt ADVENTURE 6
+.Os
+.Sh NAME
+.Nm adventure
+.Nd an exploration game
+.Sh SYNOPSIS
+.Nm
+.Op saved-file
+.Sh DESCRIPTION
+The object of the game is to locate and explore Colossal Cave, find the
+treasures hidden there, and bring them back to the building with you.
+The program is self-descriptive to a point, but part of the game is to
+discover its rules.
+.Pp
+To terminate a game, enter
+.Dq quit ;
+to save a game for later resumption, enter
+.Dq suspend .
diff --git a/games/adventure/crc.c b/games/adventure/crc.c
new file mode 100644 (file)
index 0000000..dafd762
--- /dev/null
@@ -0,0 +1,145 @@
+/*     $NetBSD: crc.c,v 1.13 2012/01/08 18:16:00 dholland Exp $        */
+
+/*-
+ * Copyright (c) 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * James W. Williams of the University of Maryland.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)crc.c      8.1 (Berkeley) 5/31/93";
+static char ORIGINAL_sccsid[] = "@(#)crc.c     5.2 (Berkeley) 4/4/91";
+#else
+__RCSID("$NetBSD: crc.c,v 1.13 2012/01/08 18:16:00 dholland Exp $");
+#endif
+#endif /* not lint */
+
+#include "extern.h"
+
+static const uint32_t crctab[256] = {
+       0x7fffffff,
+       0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+       0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e,
+       0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+       0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d,
+       0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0,
+       0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63,
+       0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+       0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa,
+       0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75,
+       0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180,
+       0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+       0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87,
+       0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+       0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5,
+       0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+       0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4,
+       0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b,
+       0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea,
+       0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+       0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541,
+       0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc,
+       0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f,
+       0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+       0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e,
+       0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+       0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c,
+       0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+       0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b,
+       0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2,
+       0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671,
+       0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+       0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8,
+       0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767,
+       0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6,
+       0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+       0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795,
+       0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+       0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b,
+       0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+       0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82,
+       0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d,
+       0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8,
+       0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+       0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff,
+       0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee,
+       0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d,
+       0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+       0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c,
+       0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+       0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02,
+       0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+/*
+ * crc --
+ *      Compute a POSIX.2 checksum.  This routine modified by Jim Gillogly
+ *      to work on sequential data rather than on a file.  Initial call to
+ *      crc_start initializes the sum, and subsequent calls to crc update
+ *      it.
+ */
+
+void
+crc_start(struct crcstate *c)
+{
+       c->crcval = 0;
+       c->step = 0;
+}
+
+/*
+ * Process NUM bytes pointed to by DATA
+ */
+void
+crc_add(struct crcstate *c, const void *data, size_t num)
+{
+       const unsigned char *udata;
+       size_t pos;
+       unsigned x;
+
+       udata = data;
+       pos = 0;
+       while (pos < num) {
+               x = (c->crcval >> 24 ^ udata[pos++]) & 0xff;
+               if (x == 0) {
+                       x = c->step++;
+                       if (c->step >= __arraycount(crctab)) {
+                               c->step = 0;
+                       }
+               }
+               c->crcval = (c->crcval << 8) ^ crctab[x];
+       }
+}
+
+uint32_t
+crc_get(struct crcstate *c)
+{
+       return c->crcval;
+}
diff --git a/games/adventure/done.c b/games/adventure/done.c
new file mode 100644 (file)
index 0000000..8693937
--- /dev/null
@@ -0,0 +1,172 @@
+/*     $NetBSD: done.c,v 1.10 2009/08/25 06:56:52 dholland Exp $       */
+
+/*-
+ * Copyright (c) 1991, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * The game adventure was originally written in Fortran by Will Crowther
+ * and Don Woods.  It was later translated to C and enhanced by Jim
+ * Gillogly.  This code is derived from software contributed to Berkeley
+ * by Jim Gillogly at The Rand Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)done.c     8.1 (Berkeley) 5/31/93";
+#else
+__RCSID("$NetBSD: done.c,v 1.10 2009/08/25 06:56:52 dholland Exp $");
+#endif
+#endif /* not lint */
+
+/*      Re-coding of advent in C: termination routines */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "hdr.h"
+#include "extern.h"
+
+int
+score(void)
+{                              /* sort of like 20000 */
+       int     myscore, i;
+
+       maxscore = myscore = 0;
+       for (i = 50; i <= maxtrs; i++) {
+               if (ptext[i].txtlen == 0)
+                       continue;
+               k = 12;
+               if (i == chest)
+                       k = 14;
+               if (i > chest)
+                       k = 16;
+               if (prop[i] >= 0)
+                       myscore += 2;
+               if (place[i] == 3 && prop[i] == 0)
+                       myscore += k - 2;
+               maxscore += k;
+       }
+       myscore += (maxdie - numdie) * 10;
+       maxscore += maxdie * 10;
+       if (!(scoring || gaveup))
+               myscore += 4;
+       maxscore += 4;
+       if (dflag != 0)
+               myscore += 25;
+       maxscore += 25;
+       if (isclosing)
+               myscore += 25;
+       maxscore += 25;
+       if (closed) {
+               if (bonus == 0)
+                       myscore += 10;
+               if (bonus == 135)
+                       myscore += 25;
+               if (bonus == 134)
+                       myscore += 30;
+               if (bonus == 133)
+                       myscore += 45;
+       }
+       maxscore += 45;
+       if (place[magazine] == 108)
+               myscore++;
+       maxscore++;
+       myscore += 2;
+       maxscore += 2;
+       for (i = 1; i <= hintmax; i++)
+               if (hinted[i])
+                       myscore -= hints[i][2];
+       return myscore;
+}
+
+/* entry=1 means goto 13000 */ /* game is over */
+/* entry=2 means goto 20000 */ /* 3=19000 */
+void
+done(int entry)
+{
+       int     i, sc;
+       if (entry == 1)
+               mspeak(1);
+       if (entry == 3)
+               rspeak(136);
+       printf("\n\n\nYou scored %d out of a ", (sc = score()));
+       printf("possible %d using %d turns.\n", maxscore, turns);
+       for (i = 1; i <= classes; i++)
+               if (cval[i] >= sc) {
+                       speak(&ctext[i]);
+                       if (i == classes - 1) {
+                               printf("To achieve the next higher rating");
+                               printf(" would be a neat trick!\n\n");
+                               printf("Congratulations!!\n");
+                               exit(0);
+                       }
+                       k = cval[i] + 1 - sc;
+                       printf("To achieve the next higher rating, you need");
+                       printf(" %d more point", k);
+                       if (k == 1)
+                               printf(".\n");
+                       else
+                               printf("s.\n");
+                       exit(0);
+               }
+       printf("You just went off my scale!!!\n");
+       exit(0);
+}
+
+/* label 90 */
+void
+die(int entry)
+{
+       int     i;
+       if (entry != 99) {
+               rspeak(23);
+               oldloc2 = loc;
+       }
+       if (isclosing) {                /* 99 */
+               rspeak(131);
+               numdie++;
+               done(2);
+       }
+       yea = yes(81 + numdie * 2, 82 + numdie * 2, 54);
+       numdie++;
+       if (numdie == maxdie || !yea)
+               done(2);
+       place[water] = 0;
+       place[oil] = 0;
+       if (toting(lamp))
+               prop[lamp] = 0;
+       for (i = 100; i >= 1; i--) {
+               if (!toting(i))
+                       continue;
+               k = oldloc2;
+               if (i == lamp)
+                       k = 1;
+               drop(i, k);
+       }
+       loc = 3;
+       oldloc = loc;
+}
diff --git a/games/adventure/extern.h b/games/adventure/extern.h
new file mode 100644 (file)
index 0000000..c0ba1ed
--- /dev/null
@@ -0,0 +1,112 @@
+/*     $NetBSD: extern.h,v 1.16 2012/01/08 18:17:41 dholland Exp $     */
+
+/*
+ * Copyright (c) 1997 Christos Zoulas.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+/* crc.c */
+struct crcstate {
+       uint32_t crcval;
+       unsigned step;
+};
+
+void crc_start(struct crcstate *);
+void crc_add(struct crcstate *, const void *, size_t);
+uint32_t crc_get(struct crcstate *);
+
+/* done.c */
+int score(void);
+void done(int) __dead;
+void die(int);
+
+/* init.c */
+void init(void);
+char   *decr(int, int, int, int, int);
+void trapdel(int);
+void startup(void);
+
+/* io.c */
+void getin(char **, char **);
+int yes(int, int, int);
+int yesm(int, int, int);
+void rdata(void);
+#ifdef DEBUG
+void twrite(int);
+#endif
+void rspeak(int);
+void mspeak(int);
+struct text;
+void speak(const struct text *);
+void pspeak(int, int);
+
+/* save.c */
+int save(const char *);
+int restore(const char *);
+
+/* subr.c */
+int toting(int);
+int here(int);
+int at(int);
+int liq(void);
+int liqloc(int);
+int forced(int);
+int dark(void);
+int pct(int);
+int fdwarf(void);
+int march(void);
+void bug(int) __dead;
+void checkhints(void);
+int trsay(void);
+int trtake(void);
+int trdrop(void);
+int tropen(void);
+int trkill(void);
+int trtoss(void);
+int trfeed(void);
+int trfill(void);
+void closing(void);
+void caveclose(void);
+
+/* vocab.c */
+void destroy(int);
+void juggle(int);
+void move(int, int);
+int put(int, int, int);
+void carry(int, int);
+void drop(int, int);
+int vocab(const char *, int, int);
+
+/* These three used to be functions in vocab.c */
+#define copystr(src, dest)     strcpy((dest), (src))
+#define weq(str1, str2)                (!strncmp((str1), (str2), 5))
+#define length(str)            (strlen((str)) + 1)
+
+/* wizard.c */
+void datime(int *, int *);
+void poof(void);
+int Start(void);
+void ciao(void);
+int ran(int);
diff --git a/games/adventure/glorkz b/games/adventure/glorkz
new file mode 100644 (file)
index 0000000..a00d400
--- /dev/null
@@ -0,0 +1,1815 @@
+1
+1      You are standing at the end of a road before a small brick building.
+1      Around you is a forest.  A small stream flows out of the building and
+1      down a gully.
+2      You have walked up a hill, still in the forest.  The road slopes back
+2      down the other side of the hill.  There is a building in the distance.
+3      You are inside a building, a well house for a large spring.
+4      You are in a valley in the forest beside a stream tumbling along a
+4      rocky bed.
+5      You are in open forest, with a deep valley to one side.
+6      You are in open forest near both a valley and a road.
+7      At your feet all the water of the stream splashes into a 2-inch slit
+7      in the rock.  Downstream the streambed is bare rock.
+8      You are in a 20-foot depression floored with bare dirt.  Set into the
+8      dirt is a strong steel grate mounted in concrete.  A dry streambed
+8      leads into the depression.
+9      You are in a small chamber beneath a 3x3 steel grate to the surface.
+9      A low crawl over cobbles leads inward to the west.
+10     You are crawling over cobbles in a low passage.  There is a dim light
+10     at the east end of the passage.
+11     You are in a debris room filled with stuff washed in from the surface.
+11     A low wide passage with cobbles becomes plugged with mud and debris
+11     here, but an awkward canyon leads upward and west.  A note on the wall
+11      says "Magic word XYZZY".
+12     You are in an awkward sloping east/west canyon.
+13     You are in a splendid chamber thirty feet high.  The walls are frozen
+13     rivers of orange stone.  An awkward canyon and a good passage exit
+13      from east and west sides of the chamber.
+14     At your feet is a small pit breathing traces of white mist.  An east
+14     passage ends here except for a small crack leading on.
+15     You are at one end of a vast hall stretching forward out of sight to
+15     the west.  There are openings to either side.  Nearby, a wide stone
+15     staircase leads downward.  The hall is filled with wisps of white mist
+15     swaying to and fro almost as if alive.  A cold wind blows up the
+15     staircase.  There is a passage at the top of a dome behind you.
+16     The crack is far too small for you to follow.
+17     You are on the east bank of a fissure slicing clear across the hall.
+17     The mist is quite thick here, and the fissure is too wide to jump.
+18     This is a low room with a crude note on the wall.  The note says,
+18     "You won't get it up the steps".
+19      You are in the Hall of the Mountain King, with passages off in all
+19     directions.
+20     You are at the bottom of the pit with a broken neck.
+21     You didn't make it.
+22     The dome is unclimbable.
+23      You are at the west end of the Twopit Room.  There is a large hole in
+23     the wall above the pit at this end of the room.
+24      You are at the bottom of the eastern pit in the Twopit Room.  There is
+24     a small pool of oil in one corner of the pit.
+25      You are at the bottom of the western pit in the Twopit Room.  There is
+25     a large hole in the wall about 25 feet above you.
+26     You clamber up the plant and scurry through the hole at the top.
+27      You are on the west side of the fissure in the Hall of Mists.
+28      You are in a low N/S passage at a hole in the floor.  The hole goes
+28      down to an E/W passage.
+29     You are in the south side chamber.
+30      You are in the west side chamber of the Hall of the Mountain King.
+30     A passage continues west and up here.
+31     >$<
+32     You can't get by the snake.
+33     You are in a large room, with a passage to the south, a passage to the
+33      west, and a wall of broken rock to the east.  There is a large "Y2" on
+33      a rock in the room's center.
+34     You are in a jumble of rock, with cracks everywhere.
+35     You're at a low window overlooking a huge pit, which extends up out of
+35     sight.  A floor is indistinctly visible over 50 feet below.  Traces of
+35      white mist cover the floor of the pit, becoming thicker to the right.
+35     Marks in the dust around the window would seem to indicate that
+35     someone has been here recently.  Directly across the pit from you and
+35      25 feet away there is a similar window looking into a lighted room.  A
+35     shadowy figure can be seen there peering back at you.
+36     You are in a dirty broken passage.  To the east is a crawl.  To the
+36     west is a large passage.  Above you is a hole to another passage.
+37     You are on the brink of a small clean climbable pit.  A crawl leads
+37     west.
+38     You are in the bottom of a small pit with a little stream, which
+38      enters and exits through tiny slits.
+39     You are in a large room full of dusty rocks.  There is a big hole in
+39     the floor.  There are cracks everywhere, and a passage leading east.
+40     You have crawled through a very low wide passage parallel to and north
+40      of the Hall of Mists.
+41      You are at the west end of Hall of Mists.  A low wide crawl continues
+41     west and another goes north.  To the south is a little passage 6 feet
+41      off the floor.
+42     You are in a maze of twisty little passages, all alike.
+43     You are in a maze of twisty little passages, all alike.
+44     You are in a maze of twisty little passages, all alike.
+45     You are in a maze of twisty little passages, all alike.
+46     Dead end
+47     Dead end
+48     Dead end
+49     You are in a maze of twisty little passages, all alike.
+50     You are in a maze of twisty little passages, all alike.
+51     You are in a maze of twisty little passages, all alike.
+52     You are in a maze of twisty little passages, all alike.
+53     You are in a maze of twisty little passages, all alike.
+54     Dead end
+55     You are in a maze of twisty little passages, all alike.
+56     Dead end
+57     You are on the brink of a thirty foot pit with a massive orange column
+57     down one wall.  You could climb down here but you could not get back
+57     up.  The maze continues at this level.
+58     Dead end
+59     You have crawled through a very low wide passage parallel to and north
+59      of the Hall of Mists.
+60     You are at the east end of a very long hall apparently without side
+60     chambers.  To the east a low wide crawl slants up.  To the north a
+60     round two foot hole slants down.
+61     You are at the west end of a very long featureless hall.  The hall
+61     joins up with a narrow north/south passage.
+62      You are at a crossover of a high N/S passage and a low E/W one.
+63     Dead end
+64     You are at a complex junction.  A low hands and knees passage from the
+64     north joins a higher crawl from the east to make a walking passage
+64     going west.  There is also a large room above.  The air is damp here.
+65      You are in Bedquilt, a long east/west passage with holes everywhere.
+65     To explore at random select north, south, up, or down.
+66      You are in a room whose walls resemble Swiss cheese.  Obvious passages
+66      go west, east, NE, and NW.  Part of the room is occupied by a large
+66     bedrock block.
+67      You are at the east end of the Twopit Room.  The floor here is
+67     littered with thin rock slabs, which make it easy to descend the pits.
+67     There is a path here bypassing the pits to connect passages from east
+67     and west.  There are holes all over, but the only big one is on the
+67     wall directly over the west pit where you can't get to it.
+68     You are in a large low circular chamber whose floor is an immense slab
+68      fallen from the ceiling (Slab Room).  East and west there once were
+68     large passages, but they are now filled with boulders.  Low small
+68     passages go north and south, and the south one quickly bends west
+68     around the boulders.
+69      You are in a secret N/S canyon above a large room.
+70      You are in a secret N/S canyon above a sizable passage.
+71     You are in a secret canyon at a junction of three canyons, bearing
+71      north, south, and SE.  The north one is as tall as the other two
+71     combined.
+72      You are in a large low room.  Crawls lead north, SE, and SW.
+73     Dead end crawl.
+74     You are in a secret canyon which here runs E/W.  It crosses over a
+74     very tight canyon 15 feet below.  If you go down you may not be able
+74     to get back up.
+75      You are at a wide place in a very tight N/S canyon.
+76     The canyon here becomes too tight to go further south.
+77      You are in a tall E/W canyon.  A low tight crawl goes 3 feet north and
+77     seems to open up.
+78     The canyon runs into a mass of boulders -- dead end.
+79     The stream flows out through a pair of 1 foot diameter sewer pipes.
+79     It would be advisable to use the exit.
+80     You are in a maze of twisty little passages, all alike.
+81     Dead end
+82     Dead end
+83     You are in a maze of twisty little passages, all alike.
+84     You are in a maze of twisty little passages, all alike.
+85     Dead end
+86     Dead end
+87     You are in a maze of twisty little passages, all alike.
+88     You are in a long, narrow corridor stretching out of sight to the
+88     west.  At the eastern end is a hole through which you can see a
+88     profusion of leaves.
+89     There is nothing here to climb.  Use "up" or "out" to leave the pit.
+90     You have climbed up the plant and out of the pit.
+91     You are at the top of a steep incline above a large room.  You could
+91     climb down here, but you would not be able to climb up.  There is a
+91     passage leading back to the north.
+92      You are in the Giant Room.  The ceiling here is too high up for your
+92     lamp to show it.  Cavernous passages lead east, north, and south.  On
+92      the west wall is scrawled the inscription, "Fee fie foe foo" [sic].
+93     The passage here is blocked by a recent cave-in.
+94     You are at one end of an immense north/south passage.
+95     You are in a magnificent cavern with a rushing stream, which cascades
+95     over a sparkling waterfall into a roaring whirlpool which disappears
+95     through a hole in the floor.  Passages exit to the south and west.
+96      You are in the Soft Room.  The walls are covered with heavy curtains,
+96     the floor with a thick pile carpet.  Moss covers the ceiling.
+97      This is the Oriental Room.  Ancient oriental cave drawings cover the
+97     walls.  A gently sloping passage leads upward to the north, another
+97      passage leads SE, and a hands and knees crawl leads west.
+98     You are following a wide path around the outer edge of a large cavern.
+98     Far below, through a heavy white mist, strange splashing noises can be
+98     heard.  The mist rises up through a fissure in the ceiling.  The path
+98     exits to the south and west.
+99      You are in an alcove.  A small NW path seems to widen after a short
+99     distance.  An extremely tight tunnel leads east.  It looks like a very
+99     tight squeeze.  An eerie light can be seen at the other end.
+100    You're in a small chamber lit by an eerie green light.  An extremely
+100    narrow tunnel exits to the west.  A dark corridor leads NE.
+101     You're in the Dark-Room.  A corridor leading south is the only exit.
+102    You are in an arched hall.  A coral passage once continued up and east
+102    from here, but is now blocked by debris.  The air smells of sea water.
+103    You're in a large room carved out of sedimentary rock.  The floor and
+103     walls are littered with bits of shells embedded in the stone.  A
+103    shallow passage proceeds downward, and a somewhat steeper one leads
+103    up.  A low hands and knees passage enters from the south.
+104    You are in a long sloping corridor with ragged sharp walls.
+105    You are in a cul-de-sac about eight feet across.
+106    You are in an anteroom leading to a large passage to the east.  Small
+106    passages go west and up.  The remnants of recent digging are evident.
+106    A sign in midair here says "Cave under construction beyond this point.
+106    Proceed at own risk.  [Witt construction company]"
+107    You are in a maze of twisty little passages, all different.
+108     You are at Witt's End.  Passages lead off in *all* directions.
+109    You are in a north/south canyon about 25 feet across.  The floor is
+109    covered by white mist seeping in from the north.  The walls extend
+109    upward for well over 100 feet.  Suspended from some unseen point far
+109    above you, an enormous two-sided mirror is hanging parallel to and
+109     midway between the canyon walls.  (The mirror is obviously provided
+109    for the use of the dwarves, who as you know, are extremely vain.)  A
+109     small window can be seen in either wall, some fifty feet up.
+110    You're at a low window overlooking a huge pit, which extends up out of
+110    sight.  A floor is indistinctly visible over 50 feet below.  Traces of
+110    white mist cover the floor of the pit, becoming thicker to the left.
+110    Marks in the dust around the window would seem to indicate that
+110    someone has been here recently.  Directly across the pit from you and
+110     25 feet away there is a similar window looking into a lighted room.  A
+110    shadowy figure can be seen there peering back at you.
+111    A large stalactite extends from the roof and almost reaches the floor
+111    below.  You could climb down it, and jump from it to the floor, but
+111    having done so you would be unable to reach it to climb back up.
+112    You are in a little maze of twisting passages, all different.
+113    You are at the edge of a large underground reservoir.  An opaque cloud
+113    of white mist fills the room and rises rapidly upward.  The lake is
+113    fed by a stream, which tumbles out of a hole in the wall about 10 feet
+113    overhead and splashes noisily into the water somewhere within the
+113     mist.  The only passage goes back toward the south.
+114    Dead end
+115    You are at the northeast end of an immense room, even larger than the
+115     Giant Room.  It appears to be a repository for the "Adventure"
+115    program.  Massive torches far overhead bathe the room with smoky
+115    yellow light.  Scattered about you can be seen a pile of bottles (all
+115    of them empty), a nursery of young beanstalks murmuring quietly, a bed
+115    of oysters, a bundle of black rods with rusty stars on their ends, and
+115    a collection of brass lanterns.  Off to one side a great many dwarves
+115    are sleeping on the floor, snoring loudly.  A sign nearby reads: "Do
+115    not disturb the dwarves!"  An immense mirror is hanging against one
+115    wall, and stretches to the other end of the room, where various other
+115    sundry objects can be glimpsed dimly in the distance.
+116     You are at the southwest end of the Repository.  To one side is a pit
+116    full of fierce green snakes.  On the other side is a row of small
+116    wicker cages, each of which contains a little sulking bird.  In one
+116    corner is a bundle of black rods with rusty marks on their ends.  A
+116    large number of velvet pillows are scattered about on the floor.  A
+116    vast mirror stretches off to the northeast.  At your feet is a large
+116     steel grate, next to which is a sign which reads, "Treasure Vault.
+116     Keys in Main Office."
+117    You are on one side of a large, deep chasm.  A heavy white mist rising
+117     up from below obscures all view of the far side.  A SW path leads away
+117    from the chasm into a winding corridor.
+118    You are in a long winding corridor sloping out of sight in both
+118    directions.
+119    You are in a secret canyon which exits to the north and east.
+120    You are in a secret canyon which exits to the north and east.
+121    You are in a secret canyon which exits to the north and east.
+122    You are on the far side of the chasm.  A NE path leads away from the
+122    chasm on this side.
+123    You're in a long east/west corridor.  A faint rumbling noise can be
+123    heard in the distance.
+124    The path forks here.  The left fork leads northeast.  A dull rumbling
+124    seems to get louder in that direction.  The right fork leads southeast
+124    down a gentle slope.  The main corridor enters from the west.
+125    The walls are quite warm here.  From the north can be heard a steady
+125    roar, so loud that the entire cave seems to be trembling.  Another
+125    passage leads south, and a low crawl goes east.
+126    You are on the edge of a breath-taking view.  Far below you is an
+126    active volcano, from which great gouts of molten lava come surging
+126    out, cascading back down into the depths.  The glowing rock fills the
+126    farthest reaches of the cavern with a blood-red glare, giving every-
+126    thing an eerie, macabre appearance.  The air is filled with flickering
+126    sparks of ash and a heavy smell of brimstone.  The walls are hot to
+126    the touch, and the thundering of the volcano drowns out all other
+126    sounds.  Embedded in the jagged roof far overhead are myriad twisted
+126    formations composed of pure white alabaster, which scatter the murky
+126    light into sinister apparitions upon the walls.  To one side is a deep
+126    gorge, filled with a bizarre chaos of tortured rock which seems to
+126    have been crafted by the devil himself.  An immense river of fire
+126    crashes out from the depths of the volcano, burns its way through the
+126    gorge, and plummets into a bottomless pit far off to your left.  To
+126    the right, an immense geyser of blistering steam erupts continuously
+126    from a barren island in the center of a sulfurous lake, which bubbles
+126    ominously.  The far right wall is aflame with an incandescence of its
+126    own, which lends an additional infernal splendor to the already
+126    hellish scene.  A dark, foreboding passage exits to the south.
+127    You are in a small chamber filled with large boulders.  The walls are
+127    very warm, causing the air in the room to be almost stifling from the
+127    heat.  The only exit is a crawl heading west, through which is coming
+127    a low rumbling.
+128    You are walking along a gently sloping north/south passage lined with
+128    oddly shaped limestone formations.
+129    You are standing at the entrance to a large, barren room.  A sign
+129    posted above the entrance reads:  "Caution!  Bear in room!"
+130    You are inside a barren room.  The center of the room is completely
+130    empty except for some dust.  Marks in the dust lead away toward the
+130    far end of the room.  The only exit is the way you came in.
+131    You are in a maze of twisting little passages, all different.
+132    You are in a little maze of twisty passages, all different.
+133    You are in a twisting maze of little passages, all different.
+134    You are in a twisting little maze of passages, all different.
+135    You are in a twisty little maze of passages, all different.
+136    You are in a twisty maze of little passages, all different.
+137    You are in a little twisty maze of passages, all different.
+138    You are in a maze of little twisting passages, all different.
+139    You are in a maze of little twisty passages, all different.
+140    Dead end
+-1     End
+2
+1      You're at end of road again.
+2      You're at hill in road.
+3      You're inside building.
+4      You're in valley.
+5      You're in forest.
+6      You're in forest.
+7      You're at slit in streambed.
+8      You're outside grate.
+9      You're below the grate.
+10      You're in Cobble Crawl.
+11      You're in Debris Room.
+13      You're in Bird Chamber.
+14     You're at top of small pit.
+15      You're in Hall of Mists.
+17     You're on east bank of fissure.
+18      You're in Nugget of Gold Room.
+19      You're in Hall of Mt King.
+23      You're at west end of Twopit Room.
+24     You're in east pit.
+25     You're in west pit.
+33      You're at "Y2".
+35     You're at window on pit.
+36     You're in dirty passage.
+39      You're in Dusty Rock room.
+41      You're at west end of Hall of Mists.
+57     You're at brink of pit.
+60      You're at east end of Long Hall.
+61      You're at west end of Long Hall.
+64      You're at Complex Junction.
+66      You're in Swiss Cheese room.
+67      You're at east end of Twopit Room.
+68      You're in Slab Room.
+71     You're at junction of three secret canyons.
+74      You're in secret E/W canyon above tight canyon.
+88     You're in narrow corridor.
+91     You're at steep incline above large room.
+92      You're in Giant Room.
+95     You're in cavern with waterfall.
+96      You're in Soft Room.
+97      You're in Oriental Room.
+98      You're in Misty Cavern.
+99      You're in Alcove.
+100     You're in Plover Room.
+101     You're in Dark-Room.
+102     You're in Arched Hall.
+103     You're in Shell Room.
+106     You're in Anteroom.
+108     You're at Witt's End.
+109     You're in Mirror Canyon.
+110     You're at window on pit.
+111    You're at top of stalactite.
+113     You're at Reservoir.
+115     You're at NE end.
+116     You're at SW end.
+117     You're on SW side of chasm.
+118    You're in sloping corridor.
+122     You're on NE side of chasm.
+123    You're in corridor.
+124    You're at fork in path.
+125    You're at junction with warm walls.
+126     You're at Breath-taking View.
+127     You're in Chamber of Boulders.
+128    You're in limestone passage.
+129    You're in front of barren room.
+130     You're in Barren Room.
+-1
+3
+1      2       2       44      29
+1      3       3       12      19      43
+1      4       5       13      14      46      30
+1      5       6       45      43
+1      8       63
+2      1       2       12      7       43      45      30
+2      5       6       45      46
+3      1       3       11      32      44
+3      11      62
+3      33      65
+3      79      5       14
+4      1       4       12      45
+4      5       6       43      44      29
+4      7       5       46      30
+4      8       63
+5      4       9       43      30
+5      50005   6       7       45
+5      6       6
+5      5       44      46
+6      1       2       45
+6      4       9       43      44      30
+6      5       6       46
+7      1       12
+7      4       4       45
+7      5       6       43      44
+7      8       5       15      16      46
+7      595     60      14      30
+8      5       6       43      44      46
+8      1       12
+8      7       4       13      45
+8      303009  3       19      30
+8      593     3
+9      303008  11      29
+9      593     11
+9      10      17      18      19      44
+9      14      31
+9      11      51
+10     9       11      20      21      43
+10     11      19      22      44      51
+10     14      31
+11     303008  63
+11     9       64
+11     10      17      18      23      24      43
+11     12      25      19      29      44
+11     3       62
+11     14      31
+12     303008  63
+12     9       64
+12     11      30      43      51
+12     13      19      29      44
+12     14      31
+13     303008  63
+13     9       64
+13     11      51
+13     12      25      43
+13     14      23      31      44
+14     303008  63
+14     9       64
+14     11      51
+14     13      23      43
+14     150020  30      31      34
+14     15      30
+14     16      33      44
+15     18      36      46
+15     17      7       38      44
+15     19      10      30      45
+15     150022  29      31      34      35      23      43
+15     14      29
+15     34      55
+16     14      1
+17     15      38      43
+17     312596  39
+17     412021  7
+17     412597  41      42      44      69
+17     27      41
+18     15      38      11      45
+19     15      10      29      43
+19     311028  45      36
+19     311029  46      37
+19     311030  44      7
+19     32      45
+19     35074   49
+19     211032  49
+19     74      66
+20     0       1
+21     0       1
+22     15      1
+23     67      43      42
+23     68      44      61
+23     25      30      31
+23     648     52
+24     67      29      11
+25     23      29      11
+25     724031  56
+25     26      56
+26     88      1
+27     312596  39
+27     412021  7
+27     412597  41      42      43      69
+27     17      41
+27     40      45
+27     41      44
+28     19      38      11      46
+28     33      45      55
+28     36      30      52
+29     19      38      11      45
+30     19      38      11      43
+30     62      44      29
+31     524089  1
+31     90      1
+32     19      1
+33     3       65
+33     28      46
+33     34      43      53      54
+33     35      44
+33     159302  71
+33     100     71
+34     33      30      55
+34     15      29
+35     33      43      55
+35     20      39
+36     37      43      17
+36     28      29      52
+36     39      44
+36     65      70
+37     36      44      17
+37     38      30      31      56
+38     37      56      29      11
+38     595     60      14      30      4       5
+39     36      43      23
+39     64      30      52      58
+39     65      70
+40     41      1
+41     42      46      29      23      56
+41     27      43
+41     59      45
+41     60      44      17
+42     41      29
+42     42      45
+42     43      43
+42     45      46
+42     80      44
+43     42      44
+43     44      46
+43     45      43
+44     43      43
+44     48      30
+44     50      46
+44     82      45
+45     42      44
+45     43      45
+45     46      43
+45     47      46
+45     87      29      30
+46     45      44      11
+47     45      43      11
+48     44      29      11
+49     50      43
+49     51      44
+50     44      43
+50     49      44
+50     51      30
+50     52      46
+51     49      44
+51     50      29
+51     52      43
+51     53      46
+52     50      44
+52     51      43
+52     52      46
+52     53      29
+52     55      45
+52     86      30
+53     51      44
+53     52      45
+53     54      46
+54     53      44      11
+55     52      44
+55     55      45
+55     56      30
+55     57      43
+56     55      29      11
+57     13      30      56
+57     55      44
+57     58      46
+57     83      45
+57     84      43
+58     57      43      11
+59     27      1
+60     41      43      29      17
+60     61      44
+60     62      45      30      52
+61     60      43
+61     62      45
+61     100107  46
+62     60      44
+62     63      45
+62     30      43
+62     61      46
+63     62      46      11
+64     39      29      56      59
+64     65      44      70
+64     103     45      74
+64     106     43
+65     64      43
+65     66      44
+65     80556   46
+65     68      61
+65     80556   29
+65     50070   29
+65     39      29
+65     60556   45
+65     75072   45
+65     71      45
+65     80556   30
+65     106     30
+66     65      47
+66     67      44
+66     80556   46
+66     77      25
+66     96      43
+66     50556   50
+66     97      72
+67     66      43
+67     23      44      42
+67     24      30      31
+68     23      46
+68     69      29      56
+68     65      45
+69     68      30      61
+69     331120  46
+69     119     46
+69     109     45
+69     113     75
+70     71      45
+70     65      30      23
+70     111     46
+71     65      48
+71     70      46
+71     110     45
+72     65      70
+72     118     49
+72     73      45
+72     97      48      72
+73     72      46      17      11
+74     19      43
+74     331120  44
+74     121     44
+74     75      30
+75     76      46
+75     77      45
+76     75      45
+77     75      43
+77     78      44
+77     66      45      17
+78     77      46
+79     3       1
+80     42      45
+80     80      44
+80     80      46
+80     81      43
+81     80      44      11
+82     44      46      11
+83     57      46
+83     84      43
+83     85      44
+84     57      45
+84     83      44
+84     114     50
+85     83      43      11
+86     52      29      11
+87     45      29      30
+88     25      30      56      43
+88     20      39
+88     92      44      27
+89     25      1
+90     23      1
+91     95      45      73      23
+91     72      30      56
+92     88      46
+92     93      43
+92     94      45
+93     92      46      27      11
+94     92      46      27      23
+94     309095  45      3       73
+94     611     45
+95     94      46      11
+95     92      27
+95     91      44
+96     66      44      11
+97     66      48
+97     72      44      17
+97     98      29      45      73
+98     97      46      72
+98     99      44
+99     98      50      73
+99     301     43      23
+99     100     43
+100    301     44      23      11
+100    99      44
+100    159302  71
+100    33      71
+100    101     47      22
+101    100     46      71      11
+102    103     30      74      11
+103    102     29      38
+103    104     30
+103    114618  46
+103    115619  46
+103    64      46
+104    103     29      74
+104    105     30
+105    104     29      11
+105    103     74
+106    64      29
+106    65      44
+106    108     43
+107    131     46
+107    132     49
+107    133     47
+107    134     48
+107    135     29
+107    136     50
+107    137     43
+107    138     44
+107    139     45
+107    61      30
+108    95556   43      45      46      47      48      49      50      29      30
+108    106     43
+108    626     44
+109    69      46
+109    113     45      75
+110    71      44
+110    20      39
+111    70      45
+111    40050   30      39      56
+111    50053   30
+111    45      30
+112    131     49
+112    132     45
+112    133     43
+112    134     50
+112    135     48
+112    136     47
+112    137     44
+112    138     30
+112    139     29
+112    140     46
+113    109     46      11      109
+114    84      48
+115    116     49
+116    115     47
+116    593     30
+117    118     49
+117    233660  41      42      69      47
+117    332661  41
+117    303     41
+117    332021  39
+117    596     39
+118    72      30
+118    117     29
+119    69      45      11
+119    653     43      7
+120    69      45
+120    74      43
+121    74      43      11
+121    653     45      7
+122    123     47
+122    233660  41      42      69      49
+122    303     41
+122    596     39
+122    124     77
+122    126     28
+122    129     40
+123    122     44
+123    124     43      77
+123    126     28
+123    129     40
+124    123     44
+124    125     47      36
+124    128     48      37      30
+124    126     28
+124    129     40
+125    124     46      77
+125    126     45      28
+125    127     43      17
+126    125     46      23      11
+126    124     77
+126    610     30      39
+127    125     44      11      17
+127    124     77
+127    126     28
+128    124     45      29      77
+128    129     46      30      40
+128    126     28
+129    128     44      29
+129    124     77
+129    130     43      19      40      3
+129    126     28
+130    129     44      11
+130    124     77
+130    126     28
+131    107     44
+131    132     48
+131    133     50
+131    134     49
+131    135     47
+131    136     29
+131    137     30
+131    138     45
+131    139     46
+131    112     43
+132    107     50
+132    131     29
+132    133     45
+132    134     46
+132    135     44
+132    136     49
+132    137     47
+132    138     43
+132    139     30
+132    112     48
+133    107     29
+133    131     30
+133    132     44
+133    134     47
+133    135     49
+133    136     43
+133    137     45
+133    138     50
+133    139     48
+133    112     46
+134    107     47
+134    131     45
+134    132     50
+134    133     48
+134    135     43
+134    136     30
+134    137     46
+134    138     29
+134    139     44
+134    112     49
+135    107     45
+135    131     48
+135    132     30
+135    133     46
+135    134     43
+135    136     44
+135    137     49
+135    138     47
+135    139     50
+135    112     29
+136    107     43
+136    131     44
+136    132     29
+136    133     49
+136    134     30
+136    135     46
+136    137     50
+136    138     48
+136    139     47
+136    112     45
+137    107     48
+137    131     47
+137    132     46
+137    133     30
+137    134     29
+137    135     50
+137    136     45
+137    138     49
+137    139     43
+137    112     44
+138    107     30
+138    131     43
+138    132     47
+138    133     29
+138    134     44
+138    135     45
+138    136     46
+138    137     48
+138    139     49
+138    112     50
+139    107     49
+139    131     50
+139    132     43
+139    133     44
+139    134     45
+139    135     30
+139    136     48
+139    137     29
+139    138     46
+139    112     47
+140    112     45      11
+-1
+4
+2      road
+2      hill
+3      enter
+4      upstr
+5      downs
+6      fores
+7      forwa
+7      conti
+7      onwar
+8      back
+8      retur
+8      retre
+9      valle
+10     stair
+11     out
+11     outsi
+11     exit
+11     leave
+12     build
+12     house
+13     gully
+14     strea
+15     rock
+16     bed
+17     crawl
+18     cobbl
+19     inwar
+19     insid
+19     in
+20     surfa
+21     null
+21     nowhe
+22     dark
+23     passa
+23     tunne
+24     low
+25     canyo
+26     awkwa
+27     giant
+28     view
+29     upwar
+29     up
+29     u
+29     above
+29     ascen
+30     d
+30     downw
+30     down
+30     desce
+31     pit
+32     outdo
+33     crack
+34     steps
+35     dome
+36     left
+37     right
+38     hall
+39     jump
+40     barre
+41     over
+42     acros
+43     east
+43     e
+44     west
+44     w
+45     north
+45     n
+46     south
+46     s
+47     ne
+48     se
+49     sw
+50     nw
+51     debri
+52     hole
+53     wall
+54     broke
+55     y2
+56     climb
+57     look
+57     exami
+57     touch
+57     descr
+58     floor
+59     room
+60     slit
+61     slab
+61     slabr
+62     xyzzy
+63     depre
+64     entra
+65     plugh
+66     secre
+67     cave
+69     cross
+70     bedqu
+71     plove
+72     orien
+73     caver
+74     shell
+75     reser
+76     main
+76     offic
+77     fork
+1001   keys
+1001   key
+1002   lamp
+1002   headl
+1002   lante
+1003   grate
+1004   cage
+1005   wand
+1005   rod
+1006   wand
+1006   rod     (must be next object after "real" rod)
+1007   steps
+1008   bird
+1009   door
+1010   pillo
+1010   velve
+1011   snake
+1012   fissu
+1013   table
+1014   clam
+1015   oyste
+1016   magaz
+1016   issue
+1016   spelu
+1016   "spel
+1017   dwarf
+1017   dwarv
+1018   knife
+1018   knive
+1019   food
+1019   ratio
+1020   bottl
+1020   jar
+1021   water
+1021   h2o
+1022   oil
+1023   mirro
+1024   plant
+1024   beans
+1025   plant   (must be next object after "real" plant)
+1026   stala
+1027   shado
+1027   figur
+1028   axe
+1029   drawi
+1030   pirat
+1031   drago
+1032   chasm
+1033   troll
+1034   troll   (must be next object after "real" troll)
+1035   bear
+1036   messa
+1037   volca
+1037   geyse   (same as volcano)
+1038   machi
+1038   vendi
+1039   batte
+1040   carpe
+1040   moss
+1050   gold
+1050   nugge
+1051   diamo
+1052   silve
+1052   bars
+1053   jewel
+1054   coins
+1055   chest
+1055   box
+1055   treas
+1056   eggs
+1056   egg
+1056   nest
+1057   tride
+1058   vase
+1058   ming
+1058   shard
+1058   potte
+1059   emera
+1060   plati
+1060   pyram
+1061   pearl
+1062   rug
+1062   persi
+1063   spice
+1064   chain
+2001   carry
+2001   take
+2001   keep
+2001   catch
+2001   steal
+2001   captu
+2001   get
+2001   tote
+2002   drop
+2002   relea
+2002   free
+2002   disca
+2002   dump
+2003   say
+2003   chant
+2003   sing
+2003   utter
+2003   mumbl
+2004   unloc
+2004   open
+2005   nothi
+2006   lock
+2006   close
+2007   light
+2007   on
+2008   extin
+2008   off
+2009   wave
+2009   shake
+2009   swing
+2010   calm
+2010   placa
+2010   tame
+2011   walk
+2011   run
+2011   trave
+2011   go
+2011   proce
+2011   conti
+2011   explo
+2011   goto
+2011   follo
+2011   turn
+2012   attac
+2012   kill
+2012   slay
+2012   fight
+2012   hit
+2012   strik
+2013   pour
+2014   eat
+2014   devou
+2015   drink
+2016   rub
+2017   throw
+2017   toss
+2018   quit
+2019   find
+2019   where
+2020   inven
+2020    inv
+2021   feed
+2022   fill
+2023   blast
+2023   deton
+2023   ignit
+2023   blowu
+2024   score
+2025   fee
+2025   fie
+2025   foe
+2025   foo
+2025   fum
+2026   brief
+2027   read
+2027   perus
+2028   break
+2028   shatt
+2028   smash
+2029   wake
+2029   distu
+2030   suspe
+2030   pause
+2030   save
+2031   hours
+3001   fee
+3002   fie
+3003   foe
+3004   foo
+3005   fum
+3050   sesam
+3050   opens
+3050   abra
+3050   abrac
+3050   shaza
+3050   hocus
+3050   pocus
+3051   help
+3051   ?
+3064   tree
+3064   trees
+3066   dig
+3066   excav
+3068   lost
+3069   mist
+3079   fuck
+3139   stop
+3142   info
+3142   infor
+3147   swim
+-1
+5
+1      Set of keys
+000    There are some keys on the ground here.
+2      Brass lantern
+000    There is a shiny brass lamp nearby.
+100    There is a lamp shining nearby.
+3      *Grate
+000    The grate is locked.
+100    The grate is open.
+4      Wicker cage
+000    There is a small wicker cage discarded nearby.
+5      Black rod
+000    A three foot black rod with a rusty star on an end lies nearby.
+6      Black rod
+000    A three foot black rod with a rusty mark on an end lies nearby.
+7      *Steps
+000    Rough stone steps lead down the pit.
+100    Rough stone steps lead up the dome.
+8      Little bird in cage
+000    A cheerful little bird is sitting here singing.
+100    There is a little bird in the cage.
+9      *Rusty door
+000    The way north is barred by a massive, rusty, iron door.
+100    The way north leads through a massive, rusty, iron door.
+10     Velvet pillow
+000    A small velvet pillow lies on the floor.
+11     *Snake
+000    A huge green fierce snake bars the way!
+100    >$<  (Chased away)
+12     *Fissure
+000    >$<
+100    A crystal bridge now spans the fissure.
+200    The crystal bridge has vanished!
+13     *Stone tablet
+000     A massive stone tablet embedded in the wall reads:
+000     "Congratulations on bringing light into the Dark-Room!"
+14     Giant clam  >grunt!<
+000    There is an enormous clam here with its shell tightly closed.
+15     Giant oyster  >groan!<
+000    There is an enormous oyster here with its shell tightly closed.
+100    Interesting.  There seems to be something written on the underside of
+100    The oyster.
+16      "Spelunker Today"
+000     There are a few recent issues of "Spelunker Today" magazine here.
+19     Tasty food
+000    There is food here.
+20     Small bottle
+000    There is a bottle of water here.
+100    There is an empty bottle here.
+200    There is a bottle of oil here.
+21     Water in the bottle
+22     Oil in the bottle
+23     *Mirror
+000    >$<
+24     *Plant
+000     There is a tiny little plant in the pit, murmuring "Water, water, ..."
+100    The plant spurts into furious growth for a few seconds.
+200    There is a 12-foot-tall beanstalk stretching up out of the pit,
+200     bellowing "WATER!! WATER!!"
+300    The plant grows explosively, almost filling the bottom of the pit.
+400    There is a gigantic beanstalk stretching all the way up to the hole.
+500    You've over-watered the plant!  It's shriveling up!  It's, it's...
+25     *Phony plant (seen in twopit room only when tall enough)
+000    >$<
+100    The top of a 12-foot-tall beanstalk is poking out of the west pit.
+200    There is a huge beanstalk growing out of the west pit up to the hole.
+26     *Stalactite
+000    >$<
+27     *Shadowy figure
+000    The shadowy figure seems to be trying to attract your attention.
+28     Dwarf's axe
+000    There is a little axe here.
+100    There is a little axe lying beside the bear.
+29     *Cave drawings
+000    >$<
+30     *Pirate
+000    >$<
+31     *Dragon
+000    A huge green fierce dragon bars the way!
+100    Congratulations!  You have just vanquished a dragon with your bare
+100     hands!  (Unbelievable, isn't it?)
+200    The body of a huge green dead dragon is lying off to one side.
+32     *Chasm
+000    A rickety wooden bridge extends across the chasm, vanishing into the
+000     mist.  A sign posted on the bridge reads, "Stop! Pay troll!"
+100    The wreckage of a bridge (and a dead bear) can be seen at the bottom
+100     of the chasm.
+33     *Troll
+000    A burly troll stands by the bridge and insists you throw him a
+000     treasure before you may cross.
+100    The troll steps out from beneath the bridge and blocks your way.
+200    >$<  (Chased away)
+34     *Phony troll
+000    The troll is nowhere to be seen.
+35     >$<  (Bear uses rtext 141)
+000    There is a ferocious cave bear eying you from the far end of the room!
+100    There is a gentle cave bear sitting placidly in one corner.
+200    There is a contented-looking bear wandering about nearby.
+300    >$<  (Dead)
+36     *Message in second maze
+000    There is a message scrawled in the dust in a flowery script, reading:
+000    "This is not the maze where the pirate leaves his treasure chest."
+37     *Volcano and/or geyser
+000    >$<
+38     *Vending machine
+000    There is a massive vending machine here.  The instructions on it read:
+000    "Drop coins here to receive fresh batteries."
+39     Batteries
+000    There are fresh batteries here.
+100    Some worn-out batteries have been discarded nearby.
+40     *Carpet and/or moss
+000    >$<
+50     Large gold nugget
+000    There is a large sparkling nugget of gold here!
+51     Several diamonds
+000    There are diamonds here!
+52     Bars of silver
+000    There are bars of silver here!
+53     Precious jewelry
+000    There is precious jewelry here!
+54     Rare coins
+000    There are many coins here!
+55     Treasure chest
+000    The pirate's treasure chest is here!
+56     Golden eggs
+000    There is a large nest here, full of golden eggs!
+100    The nest of golden eggs has vanished!
+200    Done!
+57     Jeweled trident
+000    There is a jewel-encrusted trident here!
+58     Ming vase
+000     There is a delicate, precious, Ming vase here!
+100    The vase is now resting, delicately, on a velvet pillow.
+200    The floor is littered with worthless shards of pottery.
+300     The Ming vase drops with a delicate crash.
+59     Egg-sized emerald
+000    There is an emerald here the size of a plover's egg!
+60     Platinum pyramid
+000    There is a platinum pyramid here, 8 inches on a side!
+61     Glistening pearl
+000    Off to one side lies a glistening pearl!
+62     Persian rug
+000     There is a Persian rug spread out on the floor!
+100     The dragon is sprawled out on a Persian rug!!
+63     Rare spices
+000    There are rare spices here!
+64     Golden chain
+000    There is a golden chain lying in a heap on the floor!
+100    The bear is locked to the wall with a golden chain!
+200    There is a golden chain locked to the wall!
+-1
+6
+1       Somewhere nearby is Colossal Cave, where others have found fortunes in
+1      treasure and gold, though it is rumored that some who enter are never
+1      seen again.  Magic is said to work in the cave.  I will be your eyes
+1      and hands.  Direct me with commands of 1 or 2 words.  I should warn
+1      you that I look at only the first five letters of each word, so you'll
+1      have to enter "northeast" as "ne" to distinguish it from "north".
+1       (Should you get stuck, type "help" for some general hints.  For
+1       information on how to end your adventure, etc., type "info".)
+1                                    - - -
+1       This program was originally developed by Will Crowther.  Most of the
+1       features of the current program were added by Don Woods.  Address
+1       complaints about the UNIX version to Jim Gillogly (jim@rand.org).
+2      A little dwarf with a big knife blocks your way.
+3      A little dwarf just walked around a corner, saw you, threw a little
+3       axe at you (which missed), cursed, and ran away.
+4      There is a threatening little dwarf in the room with you!
+5      One sharp nasty knife is thrown at you!
+6      None of them hit you!
+7      One of them gets you!
+8       A hollow voice says "Plugh".
+9      There is no way to go that direction.
+10     I am unsure how you are facing.  Use compass points or nearby objects.
+11     I don't know in from out here.  Use compass points or name something
+11     in the general direction you want to go.
+12     I don't know how to apply that word here.
+13     I don't understand that!
+14     I'm game.  Would you care to explain how?
+15     Sorry, but I am not allowed to give more detail.  I will repeat the
+15     long description of your location.
+16     It is now pitch dark.  If you proceed you will likely fall into a pit.
+17     If you prefer, simply type w rather than west.
+18     Are you trying to catch the bird?
+19     The bird is frightened right now and you cannot catch it no matter
+19     what you try.  Perhaps you might try later.
+20     Are you trying to somehow deal with the snake?
+21     You can't kill the snake, or drive it away, or avoid it, or anything
+21     like that.  There is a way to get by, but you don't have the necessary
+21     resources right now.
+22     Do you really want to quit now?
+23     You fell into a pit and broke every bone in your body!
+24     You are already carrying it!
+25     You can't be serious!
+26     The bird was unafraid when you entered, but as you approach it becomes
+26     disturbed and you cannot catch it.
+27     You can catch the bird, but you cannot carry it.
+28     There is nothing here with a lock!
+29     You aren't carrying it!
+30     The little bird attacks the green snake, and in an astounding flurry
+30     drives the snake away.
+31     You have no keys!
+32     It has no lock.
+33     I don't know how to lock or unlock such a thing.
+34     It was already locked.
+35     The grate is now locked.
+36     The grate is now unlocked.
+37     It was already unlocked.
+38     You have no source of light.
+39     Your lamp is now on.
+40     Your lamp is now off.
+41     There is no way to get past the bear to unlock the chain, which is
+41     probably just as well.
+42     Nothing happens.
+43     Where?
+44     There is nothing here to attack.
+45     The little bird is now dead.  Its body disappears.
+46     Attacking the snake both doesn't work and is very dangerous.
+47     You killed a little dwarf.
+48     You attack a little dwarf, but he dodges out of the way.
+49     With what?  Your bare hands?
+50     Good try, but that is an old worn-out magic word.
+51     I know of places, actions, and things.  Most of my vocabulary
+51     describes places and is used to move you there.  To move, try words
+51     like forest, building, downstream, enter, east, west, north, south,
+51     up, or down.  I know about a few special objects, like a black rod
+51     hidden in the cave.  These objects can be manipulated using some of
+51     the action words that I know.  Usually you will need to give both the
+51     object and action words (in either order), but sometimes I can infer
+51     the object from the verb alone.  Some objects also imply verbs; in
+51     particular, "inventory" implies "take inventory", which causes me to
+51     give you a list of what you're carrying.  The objects have side
+51     effects; for instance, the rod scares the bird.  Usually people having
+51     trouble moving just need to try a few more words.  Usually people
+51     trying unsuccessfully to manipulate an object are attempting something
+51     beyond their (or my!) capabilities and should try a completely
+51     different tack.  To speed the game you can sometimes move long
+51     distances with a single word.  For example, "building" usually gets
+51     you to the building from anywhere above ground except when lost in the
+51     forest.  Also, note that cave passages turn a lot, and that leaving a
+51     room to the north does not guarantee entering the next from the south.
+51     Good luck!
+52     It misses!
+53     It gets you!
+54     OK
+55     You can't unlock the keys.
+56     You have crawled around in some little holes and wound up back in the
+56     main passage.
+57     I don't know where the cave is, but hereabouts no stream can run on
+57     the surface for long.  I would try the stream.
+58     I need more detailed instructions to do that.
+59     I can only tell you what you see as you move about and manipulate
+59     things.  I cannot tell you where remote things are.
+60     I don't know that word.
+61     What?
+62     Are you trying to get into the cave?
+63     The grate is very solid and has a hardened steel lock.  You cannot
+63     enter without a key, and there are no keys nearby.  I would recommend
+63     looking elsewhere for the keys.
+64     The trees of the forest are large hardwood oak and maple, with an
+64     occasional grove of pine or spruce.  There is quite a bit of under-
+64     growth, largely birch and ash saplings plus nondescript bushes of
+64     various sorts.  This time of year visibility is quite restricted by
+64     all the leaves, but travel is quite easy if you detour around the
+64     spruce and berry bushes.
+65      Welcome to Adventure!!  Would you like instructions?
+66     Digging without a shovel is quite impractical.  Even with a shovel
+66     progress is unlikely.
+67     Blasting requires dynamite.
+68     I'm as confused as you are.
+69     Mist is a white vapor, usually water, seen from time to time in
+69     caverns.  It can be found anywhere but is frequently a sign of a deep
+69     pit leading down to water.
+70     Your feet are now wet.
+71     I think I just lost my appetite.
+72     Thank you, it was delicious!
+73     You have taken a drink from the stream.  The water tastes strongly of
+73     minerals, but is not unpleasant.  It is extremely cold.
+74     The bottle of water is now empty.
+75     Rubbing the electric lamp is not particularly rewarding.  Anyway,
+75     nothing exciting happens.
+76     Peculiar.  Nothing unexpected happens.
+77     Your bottle is empty and the ground is wet.
+78     You can't pour that.
+79     Watch it!
+80     Which way?
+81     Oh dear, you seem to have gotten yourself killed.  I might be able to
+81      help you out, but I've never really done this before.  Do you want me
+81     to try to reincarnate you?
+82     All right.  But don't blame me if something goes wr......
+82                         --- Poof!! ---
+82     You are engulfed in a cloud of orange smoke.  Coughing and gasping,
+82     you emerge from the smoke and find....
+83     You clumsy oaf, you've done it again!  I don't know how long I can
+83     keep this up.  Do you want me to try reincarnating you again?
+84     Okay, now where did I put my orange smoke?....  >poof!<
+84     Everything disappears in a dense cloud of orange smoke.
+85     Now you've really done it!  I'm out of orange smoke!  You don't expect
+85     me to do a decent reincarnation without any orange smoke, do you?
+86     Okay, if you're so smart, do it yourself!  I'm leaving!
+90     >>> Messages 81 thru 90 are reserved for "obituaries". <<<
+91     Sorry, but I no longer seem to remember how it was you got here.
+92     You can't carry anything more.  You'll have to drop something first.
+93     You can't go through a locked steel grate!
+94     I believe what you want is right here with you.
+95     You don't fit through a two-inch slit!
+96     I respectfully suggest you go across the bridge instead of jumping.
+97     There is no way across the fissure.
+98     You're not carrying anything.
+99     You are currently holding the following:
+100    It's not hungry (it's merely pinin' for the fjords).  Besides, you
+100    have no bird seed.
+101    The snake has now devoured your bird.
+102    There's nothing here it wants to eat (except perhaps you).
+103    You fool, dwarves eat only coal!  Now you've made him *really* mad!!
+104    You have nothing in which to carry it.
+105    Your bottle is already full.
+106    There is nothing here with which to fill the bottle.
+107    Your bottle is now full of water.
+108    Your bottle is now full of oil.
+109    You can't fill that.
+110    Don't be ridiculous!
+111    The door is extremely rusty and refuses to open.
+112    The plant indignantly shakes the oil off its leaves and asks, "water?"
+113    The hinges are quite thoroughly rusted now and won't budge.
+114    The oil has freed up the hinges so that the door will now move,
+114    although it requires some effort.
+115    The plant has exceptionally deep roots and cannot be pulled free.
+116    The dwarves' knives vanish as they strike the walls of the cave.
+117    Something you're carrying won't fit through the tunnel with you.
+117    You'd best take inventory and drop something.
+118    You can't fit this five-foot clam through that little passage!
+119    You can't fit this five-foot oyster through that little passage!
+120    I advise you to put down the clam before opening it.  >strain!<
+121    I advise you to put down the oyster before opening it.  >wrench!<
+122    You don't have anything strong enough to open the clam.
+123    You don't have anything strong enough to open the oyster.
+124    A glistening pearl falls out of the clam and rolls away.  Goodness,
+124    this must really be an oyster.  (I never was very good at identifying
+124    bivalves.)  Whatever it is, it has now snapped shut again.
+125    The oyster creaks open, revealing nothing but oyster inside.  It
+125    promptly snaps shut again.
+126    You have crawled around in some little holes and found your way
+126    blocked by a recent cave-in.  You are now back in the main passage.
+127    There are faint rustling noises from the darkness behind you.
+128    Out from the shadows behind you pounces a bearded pirate!  "Har, har,"
+128    he chortles, "I'll just take all this booty and hide it away with me
+128    chest deep in the maze!"  He snatches your treasure and vanishes into
+128    the gloom.
+129    A sepulchral voice reverberating through the cave, says, "Cave closing
+129     soon.  All adventurers exit immediately through Main Office."
+130    A mysterious recorded voice groans into life and announces:
+130        "This exit is closed.  Please leave via Main Office."
+131    It looks as though you're dead.  Well, seeing as how it's so close to
+131    closing time anyway, I think we'll just call it a day.
+132     The sepulchral voice intones, "The cave is now closed."  As the echoes
+132    fade, there is a blinding flash of light (and a small puff of orange
+132     smoke). . . .    As your eyes refocus, you look around and find...
+133     There is a loud explosion, and a twenty-foot hole appears in the far
+133    wall, burying the dwarves in the rubble.  You march through the hole
+133     and find yourself in the Main Office, where a cheering band of
+133    friendly elves carry the conquering adventurer off into the sunset.
+134    There is a loud explosion, and a twenty-foot hole appears in the far
+134    wall, burying the snakes in the rubble.  A river of molten lava pours
+134    in through the hole, destroying everything in its path, including you!
+135    There is a loud explosion, and you are suddenly splashed across the
+135    walls of the room.
+136    The resulting ruckus has awakened the dwarves.  There are now several
+136    threatening little dwarves in the room with you!  Most of them throw
+136    knives at you!  All of them get you!
+137    Oh, leave the poor unhappy bird alone.
+138     I dare say whatever you want is around here somewhere.
+139    I don't know the word "stop".  Use "quit" if you want to give up.
+140    You can't get there from here.
+141    You are being followed by a very large, tame bear.
+142    If you want to end your adventure early, say "quit".  To suspend your
+142    adventure such that you can continue later, say "suspend" (or "pause"
+142     or "save").  To see what hours the cave is normally open, say "hours".
+142    To see how well you're doing, say "score".  To get full credit for a
+142    treasure, you must have left it safely in the building, though you get
+142    partial credit just for locating it.  You lose points for getting
+142    killed, or for quitting, though the former costs you more.  There are
+142    also points based on how much (if any) of the cave you've managed to
+142    explore; in particular, there is a large bonus just for getting in (to
+142    distinguish the beginners from the rest of the pack), and there are
+142    other ways to determine whether you've been through some of the more
+142    harrowing sections.  If you think you've found all the treasures, just
+142    keep exploring for a while.  If nothing interesting happens, you
+142    haven't found them all yet.  If something interesting *does* happen,
+142    it means you're getting a bonus and have an opportunity to garner many
+142     more points in the Master's Section.  I may occasionally offer hints
+142    if you seem to be having trouble.  If I do, I'll warn you in advance
+142    how much it will affect your score to accept the hints.  Finally, to
+142    save paper, you may specify "brief", which tells me never to repeat
+142    the full description of a place unless you explicitly ask me to.
+143    Do you indeed wish to quit now?
+144    There is nothing here with which to fill the vase.
+145    The sudden change in temperature has delicately shattered the vase.
+146    It is beyond your power to do that.
+147    I don't know how.
+148    It is too far up for you to reach.
+149    You killed a little dwarf.  The body vanishes in a cloud of greasy
+149    black smoke.
+150    The shell is very strong and is impervious to attack.
+151    What's the matter, can't you read?  Now you'd best start over.
+152    The axe bounces harmlessly off the dragon's thick scales.
+153    The dragon looks rather nasty.  You'd best not try to get by.
+154    The little bird attacks the green dragon, and in an astounding flurry
+154    gets burnt to a cinder.  The ashes blow away.
+155    On what?
+156     Okay, from now on I'll only describe a place in full the first time
+156    you come to it.  To get the full description, say "look".
+157    Trolls are close relatives with the rocks and have skin as tough as
+157    that of a rhinoceros.  The troll fends off your blows effortlessly.
+158    The troll deftly catches the axe, examines it carefully, and tosses it
+158     back, declaring, "Good workmanship, but it's not valuable enough."
+159    The troll catches your treasure and scurries away out of sight.
+160    The troll refuses to let you cross.
+161    There is no longer any way across the chasm.
+162    Just as you reach the other side, the bridge buckles beneath the
+162    weight of the bear, which was still following you around.  You
+162    scrabble desperately for support, but as the bridge collapses you
+162    stumble back and fall into the chasm.
+163    The bear lumbers toward the troll, who lets out a startled shriek and
+163    scurries away.  The bear soon gives up the pursuit and wanders back.
+164    The axe misses and lands near the bear where you can't get at it.
+165    With what?  Your bare hands?  Against *his* bear hands??
+166    The bear is confused; he only wants to be your friend.
+167    For crying out loud, the poor thing is already dead!
+168    The bear eagerly wolfs down your food, after which he seems to calm
+168     down considerably and even becomes rather friendly.
+169    The bear is still chained to the wall.
+170    The chain is still locked.
+171    The chain is now unlocked.
+172    The chain is now locked.
+173    There is nothing here to which the chain can be locked.
+174    There is nothing here to eat.
+175    Do you want the hint?
+176    Do you need help getting out of the maze?
+177    You can make the passages look less alike by dropping things.
+178     Are you trying to explore beyond the Plover Room?
+179    There is a way to explore that region without having to worry about
+179    falling into a pit.  None of the objects available is immediately
+179    useful in discovering the secret.
+180    Do you need help getting out of here?
+181    Don't go west.
+182    Gluttony is not one of the troll's vices.  Avarice, however, is.
+183    Your lamp is getting dim.  You'd best start wrapping this up, unless
+183    You can find some fresh batteries.  I seem to recall there's a vending
+183    machine in the maze.  Bring some coins with you.
+184    Your lamp has run out of power.
+185    There's not much point in wandering around out here, and you can't
+185    explore the cave without a lamp.  So let's just call it a day.
+186    There are faint rustling noises from the darkness behind you.  As you
+186    turn toward them, the beam of your lamp falls across a bearded pirate.
+186    He is carrying a large chest.  "Shiver me timbers!" he cries, "I've
+186    been spotted!  I'd best hie meself off to the maze to hide me chest!"
+186    With that, he vanishes into the gloom.
+187    Your lamp is getting dim.  You'd best go back for those batteries.
+188    Your lamp is getting dim.  I'm taking the liberty of replacing the
+188    batteries.
+189    Your lamp is getting dim, and you're out of spare batteries.  You'd
+189    best start wrapping this up.
+190     I'm afraid the magazine is written in Dwarvish.
+191    "This is not the maze where the pirate leaves his treasure chest."
+192    Hmmm, this looks like a clue, which means it'll cost you 10 points to
+192    read it.  Should I go ahead and read it anyway?
+193    It says, "there is something strange about this place, such that one
+193     of the words I've always known now has a new effect."
+194    It says the same thing it did before.
+195    I'm afraid I don't understand.
+196     "Congratulations on bringing light into the Dark-Room!"
+197    You strike the mirror a resounding blow, whereupon it shatters into a
+197    myriad tiny fragments.
+198    You have taken the vase and hurled it delicately to the ground.
+199    You prod the nearest dwarf, who wakes up grumpily, takes one look at
+199    you, curses, and grabs for his axe.
+200    Is this acceptable?
+201    There's no point in suspending a demonstration game.
+202     You awaken only to discover your bits have been dissolving while you
+202     slept.  You disappear in a cloud of greasy black smoke.
+-1
+7
+1      3
+2      3
+3      8       9
+4      10
+5      11
+6      0
+7      14      15
+8      13
+9      94      -1
+10     96
+11     19      -1
+12     17      27
+13     101     -1
+14     103
+15     0
+16     106
+17     0       -1
+18     0
+19     3
+20     3
+21     0
+22     0
+23     109     -1
+24     25      -1
+25     23      67
+26     111     -1
+27     35      110
+28     0
+29     97      -1
+30     0       -1
+31     119     121
+32     117     122
+33     117     122
+34     0       0
+35     130     -1
+36     0       -1
+37     126     -1
+38     140     -1
+39     0
+40     96      -1
+50     18
+51     27
+52     28
+53     29
+54     30
+55     0
+56     92
+57     95
+58     97
+59     100
+60     101
+61     0
+62     119     121
+63     127
+64     130     -1
+-1
+8
+1      24
+2      29
+3      0
+4      33
+5      0
+6      33
+7      38
+8      38
+9      42
+10     14
+11     43
+12     110
+13     29
+14     110
+15     73
+16     75
+17     29
+18     13
+19     59
+20     59
+21     174
+22     109
+23     67
+24     13
+25     147
+26     155
+27     195
+28     146
+29     110
+30     13
+31     13
+-1
+9
+0      1       2       3       4       5       6       7       8       9       10
+0      100     115     116     126
+2      1       3       4       7       38      95      113     24
+1      24
+3      46      47      48      54      56      58      82      85      86
+3      122     123     124     125     126     127     128     129     130
+4      8
+5      13
+6      19
+7      42      43      44      45      46      47      48      49      50      51
+7      52      53      54      55      56      80      81      82      86      87
+8      99      100     101
+9      108
+-1
+10
+35     You are obviously a rank amateur.  Better luck next time.
+100     Your score qualifies you as a Novice class Adventurer.
+130     You have achieved the rating: "Experienced Adventurer".
+200     You may now consider yourself a "Seasoned Adventurer".
+250     You have reached "Junior Master" status.
+300     Your score puts you in Master Adventurer Class C.
+330     Your score puts you in Master Adventurer Class B.
+349     Your score puts you in Master Adventurer Class A.
+9999    All of Adventuredom gives tribute to you, Adventurer Grandmaster!
+-1
+11
+2      9999    10      0       0
+3      9999    5       0       0
+4      4       2       62      63
+5      5       2       18      19
+6      8       2       20      21
+7      75      4       176     177
+8      25      5       178     179
+9      20      3       180     181
+-1
+12
+1      A large cloud of green smoke appears in front of you.  It clears away
+1      to reveal a tall wizard, clothed in grey.  He fixes you with a steely
+1       glare and declares, "This adventure has lasted too long."  With that
+1      he makes a single pass over you with his hands, and everything around
+1       you fades away into a grey nothingness.
+2      Even wizards have to wait longer than that!
+3       I'm terribly sorry, but Colossal Cave is closed.  Our hours are:
+4      Only wizards are permitted within the cave right now.
+5      We do allow visitors to make short explorations during our off hours.
+5      Would you like to do that?
+6       Colossal Cave is open to regular adventurers at the following hours:
+7      Very well.
+8      Only a wizard may continue an adventure this soon.
+9      I suggest you resume your adventure at a later time.
+10     Do you wish to see the hours?
+11     Do you wish to change the hours?
+12     New magic word (null to leave unchanged):
+13     New magic number (null to leave unchanged):
+14     Do you wish to change the message of the day?
+15     Okay.  You can save this version now.
+16     Are you a wizard?
+17     Prove it!  Say the magic word!
+18     That is not what I thought it was.  Do you know what I thought it was?
+19     Oh dear, you really *are* a wizard!  Sorry to have bothered you . . .
+20     Foo, you are nothing but a charlatan!
+21     New hours specified by defining "prime time".  Give only the hour
+21     (E.g. 14, not 14:00 or 2pm).  Enter a negative number after last pair.
+22      New hours for Colossal Cave:
+23     Limit lines to 70 chars.  End with null line.
+24     Line too long, retype:
+25     Not enough room for another line.  Ending message here.
+26     Do you wish to (re)schedule the next holiday?
+27     To begin how many days from today?
+28     To last how many days (zero if no holiday)?
+29     To be called what (up to 20 characters)?
+30     Too small!  Assuming minimum value (45 minutes).
+31     Break out of this and save your core-image.
+32     Be sure to save your core-image...
+-1
+0
+       glorkz     8.1     93/05/31
diff --git a/games/adventure/hdr.h b/games/adventure/hdr.h
new file mode 100644 (file)
index 0000000..8a2359f
--- /dev/null
@@ -0,0 +1,157 @@
+/*     $NetBSD: hdr.h,v 1.13 2009/08/25 06:56:52 dholland Exp $        */
+
+/*-
+ * Copyright (c) 1991, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * The game adventure was originally written in Fortran by Will Crowther
+ * and Don Woods.  It was later translated to C and enhanced by Jim
+ * Gillogly.  This code is derived from software contributed to Berkeley
+ * by Jim Gillogly at The Rand Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)hdr.h       8.1 (Berkeley) 5/31/93
+ */
+
+/*   ADVENTURE -- Jim Gillogly, Jul 1977
+ * This program is a re-write of ADVENT, written in FORTRAN mostly by
+ * Don Woods of SAIL.  In most places it is as nearly identical to the
+ * original as possible given the language and word-size differences.
+ * A few places, such as the message arrays and travel arrays were changed
+ * to reflect the smaller core size and word size.  The labels of the
+ * original are reflected in this version, so that the comments of the
+ * fortran are still applicable here.
+ *
+ * The data file distributed with the fortran source is assumed to be called
+ * "glorkz" in the directory where the program is first run.
+ *
+ * The original FORTRAN version can be found at
+ * <URL:ftp://ftp.gmd.de/if-archive/games/source/advent-original.tar.gz>.
+ */
+
+/* hdr.h: included by c advent files */
+
+#include <signal.h>
+
+extern volatile sig_atomic_t delhit;
+extern int     yea;
+extern char data_file[];       /* Virtual data file */
+
+#define TAB     011
+#define LF      012
+#define FLUSHLINE do { int flushline_ch; while ((flushline_ch = getchar()) != EOF && flushline_ch != '\n'); } while (0)
+#define FLUSHLF   while (next()!=LF)
+
+extern int     loc, newloc, oldloc, oldloc2, wasdark, gaveup, kq, k, k2;
+extern char   *wd1, *wd2;              /* the complete words */
+extern int     verb, obj, spk;
+extern int blklin;
+extern int     saveday, savet, maxscore, latency;
+
+#define SHORT 50               /* How short is a demo game? */
+
+#define MAXSTR  20             /* max length of user's words */
+
+#define HTSIZE  512            /* max number of vocab words */
+extern struct hashtab {                /* hash table for vocabulary */
+       int     val;            /* word type &index (ktab) */
+       char   *atab;           /* pointer to actual string */
+}       voc[HTSIZE];
+#define SEED 1815622           /* "Encryption" seed */
+
+struct text {
+       char   *seekadr;/* Msg start in virtual disk */
+       int     txtlen; /* length of msg starting here */
+};
+
+#define RTXSIZE 205
+extern struct text rtext[RTXSIZE];     /* random text messages */
+
+#define MAGSIZE 35
+extern struct text mtext[MAGSIZE];     /* magic messages */
+
+extern int     classes;
+#define CLSMAX  12
+extern struct text ctext[CLSMAX];      /* classes of adventurer */
+extern int     cval[CLSMAX];
+
+extern struct text ptext[101];         /* object descriptions */
+
+#define LOCSIZE 141                    /* number of locations */
+extern struct text ltext[LOCSIZE];     /* long loc description */
+extern struct text stext[LOCSIZE];     /* short loc descriptions */
+
+extern struct travlist {               /* direcs & conditions of travel */
+       struct travlist *next;  /* ptr to next list entry */
+       int     conditions;     /* m in writeup (newloc / 1000) */
+       int     tloc;           /* n in writeup (newloc % 1000) */
+       int     tverb;          /* the verb that takes you there */
+}      *travel[LOCSIZE], *tkk; /* travel is closer to keys(...) */
+
+extern int     atloc[LOCSIZE];
+
+extern int     plac[101];              /* initial object placement */
+extern int     fixd[101], fixed[101];  /* location fixed? */
+
+extern int     actspeak[35];           /* rtext msg for verb <n> */
+
+extern int     cond[LOCSIZE];          /* various condition bits */
+
+extern int     setbit[16];             /* bit defn masks 1,2,4,... */
+
+extern int     hintmax;
+extern int     hints[20][5];           /* info on hints */
+extern int     hinted[20], hintlc[20];
+
+extern int     place[101], prop[101], links[201];
+extern int     abb[LOCSIZE];
+
+extern int     maxtrs, tally, tally2;  /* treasure values */
+
+#define FALSE   0
+#define TRUE    1
+
+extern int     keys, lamp, grate, cage, rod, rod2, steps,      /* mnemonics */
+               bird, door, pillow, snake, fissure, tablet, clam, oyster,
+               magazine, dwarf, knife, food, bottle, water, oil, plant, plant2,
+               axe, mirror, dragon, chasm, troll, troll2, bear, message,
+               vend, batter, nugget, coins, chest, eggs, trident, vase,
+               emerald, pyramid, pearl, rug, chain, spices, back, look, cave,
+               null, entrance, depression, /*enter, stream, pour,*/ say, lock,
+               throw, find, invent;
+
+extern int     chloc, chloc2, dseen[7], dloc[7],       /* dwarf stuff */
+               odloc[7], dflag, daltloc;
+
+extern int     tk[21], stick, dtotal, attack;
+extern int     turns, lmwarn, iwest, knfloc, detail,   /* various flags and
+                                                        * counters */
+               abbnum, maxdie, numdie, holding, dkill, foobar, bonus, clock1,
+               clock2, saved, isclosing, panic, closed, scoring;
+
+extern int     demo, limit;
+
+#define DECR(a,b,c,d,e) decr(a+'+',b+'-',c+'#',d+'&',e+'%')
diff --git a/games/adventure/init.c b/games/adventure/init.c
new file mode 100644 (file)
index 0000000..bb316c5
--- /dev/null
@@ -0,0 +1,302 @@
+/*     $NetBSD: init.c,v 1.20 2011/08/31 16:24:55 plunky Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * The game adventure was originally written in Fortran by Will Crowther
+ * and Don Woods.  It was later translated to C and enhanced by Jim
+ * Gillogly.  This code is derived from software contributed to Berkeley
+ * by Jim Gillogly at The Rand Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)init.c     8.1 (Berkeley) 6/2/93";
+#else
+__RCSID("$NetBSD: init.c,v 1.20 2011/08/31 16:24:55 plunky Exp $");
+#endif
+#endif /* not lint */
+
+/*      Re-coding of advent in C: data initialization */
+
+#include <sys/types.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "hdr.h"
+#include "extern.h"
+
+static void linkdata(void);
+
+int     blklin = TRUE;
+
+int     setbit[16] = {1, 2, 4, 010, 020, 040, 0100, 0200, 0400, 01000, 02000, 
+                     04000, 010000, 020000, 040000, 0100000};
+
+volatile sig_atomic_t delhit;
+int     yea;
+
+int     loc, newloc, oldloc, oldloc2, wasdark, gaveup, kq, k, k2;
+char   *wd1, *wd2;             /* the complete words */
+int     verb, obj, spk;
+int     saveday, savet, maxscore, latency;
+
+struct hashtab voc[HTSIZE];
+
+struct text rtext[RTXSIZE];    /* random text messages */
+
+struct text mtext[MAGSIZE];    /* magic messages */
+
+int     classes;
+
+struct text ctext[CLSMAX];     /* classes of adventurer */
+int     cval[CLSMAX];
+
+struct text ptext[101];                /* object descriptions */
+
+struct text ltext[LOCSIZE];    /* long loc description */
+struct text stext[LOCSIZE];    /* short loc descriptions */
+
+struct travlist *travel[LOCSIZE], *tkk;        /* travel is closer to keys(...) */
+
+int     atloc[LOCSIZE];
+
+int     plac[101];             /* initial object placement */
+int     fixd[101], fixed[101]; /* location fixed? */
+
+int     actspeak[35];          /* rtext msg for verb <n> */
+
+int     cond[LOCSIZE];         /* various condition bits */
+
+int     hintmax;
+int     hints[20][5];          /* info on hints */
+int     hinted[20], hintlc[20];
+
+int     place[101], prop[101], links[201];
+int     abb[LOCSIZE];
+
+int     maxtrs, tally, tally2; /* treasure values */
+
+int     keys, lamp, grate, cage, rod, rod2, steps,     /* mnemonics */
+        bird, door, pillow, snake, fissure, tablet, clam, oyster,
+        magazine, dwarf, knife, food, bottle, water, oil, plant, plant2,
+        axe, mirror, dragon, chasm, troll, troll2, bear, message,
+        vend, batter, nugget, coins, chest, eggs, trident, vase,
+        emerald, pyramid, pearl, rug, chain, spices, back, look, cave,
+        null, entrance, depression, say, lock, throw,
+        find, invent;
+
+static int enter, /*stream,*/ pour;
+
+int     chloc, chloc2, dseen[7], dloc[7],      /* dwarf stuff */
+        odloc[7], dflag, daltloc;
+
+int     tk[21], stick, dtotal, attack;
+int     turns, lmwarn, iwest, knfloc, detail,  /* various flags and
+                                                * counters */
+        abbnum, maxdie, numdie, holding, dkill, foobar, bonus, clock1,
+        clock2, saved, isclosing, panic, closed, scoring;
+
+int     demo, limit;
+
+/* everything for 1st time run */
+void
+init(void)
+{
+       rdata();                /* read data from orig. file */
+       linkdata();
+       poof();
+}
+
+char *
+decr(int a, int b, int c, int d, int e)
+{
+       static char buf[6];
+
+       buf[0] = a - '+';
+       buf[1] = b - '-';
+       buf[2] = c - '#';
+       buf[3] = d - '&';
+       buf[4] = e - '%';
+       buf[5] = 0;
+       return buf;
+}
+
+static void
+linkdata(void)
+{                              /* secondary data manipulation */
+       int     i, j;
+
+       /* array linkages */
+       for (i = 1; i < LOCSIZE; i++)
+               if (ltext[i].seekadr != 0 && travel[i] != 0)
+                       if ((travel[i]->tverb) == 1)
+                               cond[i] = 2;
+       for (j = 100; j > 0; j--)
+               if (fixd[j] > 0) {
+                       drop(j + 100, fixd[j]);
+                       drop(j, plac[j]);
+               }
+       for (j = 100; j > 0; j--) {
+               fixed[j] = fixd[j];
+               if (plac[j] != 0 && fixd[j] <= 0)
+                       drop(j, plac[j]);
+       }
+
+       maxtrs = 79;
+       tally = 0;
+       tally2 = 0;
+
+       for (i = 50; i <= maxtrs; i++) {
+               if (ptext[i].seekadr != 0)
+                       prop[i] = -1;
+               tally -= prop[i];
+       }
+
+       /* define mnemonics */
+       keys = vocab(DECR('k', 'e', 'y', 's', '\0'), 1, 0);
+       lamp = vocab(DECR('l', 'a', 'm', 'p', '\0'), 1, 0);
+       grate = vocab(DECR('g', 'r', 'a', 't', 'e'), 1, 0);
+       cage = vocab(DECR('c', 'a', 'g', 'e', '\0'), 1, 0);
+       rod = vocab(DECR('r', 'o', 'd', '\0', '\0'), 1, 0);
+       rod2 = rod + 1;
+       steps = vocab(DECR('s', 't', 'e', 'p', 's'), 1, 0);
+       bird = vocab(DECR('b', 'i', 'r', 'd', '\0'), 1, 0);
+       door = vocab(DECR('d', 'o', 'o', 'r', '\0'), 1, 0);
+       pillow = vocab(DECR('p', 'i', 'l', 'l', 'o'), 1, 0);
+       snake = vocab(DECR('s', 'n', 'a', 'k', 'e'), 1, 0);
+       fissure = vocab(DECR('f', 'i', 's', 's', 'u'), 1, 0);
+       tablet = vocab(DECR('t', 'a', 'b', 'l', 'e'), 1, 0);
+       clam = vocab(DECR('c', 'l', 'a', 'm', '\0'), 1, 0);
+       oyster = vocab(DECR('o', 'y', 's', 't', 'e'), 1, 0);
+       magazine = vocab(DECR('m', 'a', 'g', 'a', 'z'), 1, 0);
+       dwarf = vocab(DECR('d', 'w', 'a', 'r', 'f'), 1, 0);
+       knife = vocab(DECR('k', 'n', 'i', 'f', 'e'), 1, 0);
+       food = vocab(DECR('f', 'o', 'o', 'd', '\0'), 1, 0);
+       bottle = vocab(DECR('b', 'o', 't', 't', 'l'), 1, 0);
+       water = vocab(DECR('w', 'a', 't', 'e', 'r'), 1, 0);
+       oil = vocab(DECR('o', 'i', 'l', '\0', '\0'), 1, 0);
+       plant = vocab(DECR('p', 'l', 'a', 'n', 't'), 1, 0);
+       plant2 = plant + 1;
+       axe = vocab(DECR('a', 'x', 'e', '\0', '\0'), 1, 0);
+       mirror = vocab(DECR('m', 'i', 'r', 'r', 'o'), 1, 0);
+       dragon = vocab(DECR('d', 'r', 'a', 'g', 'o'), 1, 0);
+       chasm = vocab(DECR('c', 'h', 'a', 's', 'm'), 1, 0);
+       troll = vocab(DECR('t', 'r', 'o', 'l', 'l'), 1, 0);
+       troll2 = troll + 1;
+       bear = vocab(DECR('b', 'e', 'a', 'r', '\0'), 1, 0);
+       message = vocab(DECR('m', 'e', 's', 's', 'a'), 1, 0);
+       vend = vocab(DECR('v', 'e', 'n', 'd', 'i'), 1, 0);
+       batter = vocab(DECR('b', 'a', 't', 't', 'e'), 1, 0);
+
+       nugget = vocab(DECR('g', 'o', 'l', 'd', '\0'), 1, 0);
+       coins = vocab(DECR('c', 'o', 'i', 'n', 's'), 1, 0);
+       chest = vocab(DECR('c', 'h', 'e', 's', 't'), 1, 0);
+       eggs = vocab(DECR('e', 'g', 'g', 's', '\0'), 1, 0);
+       trident = vocab(DECR('t', 'r', 'i', 'd', 'e'), 1, 0);
+       vase = vocab(DECR('v', 'a', 's', 'e', '\0'), 1, 0);
+       emerald = vocab(DECR('e', 'm', 'e', 'r', 'a'), 1, 0);
+       pyramid = vocab(DECR('p', 'y', 'r', 'a', 'm'), 1, 0);
+       pearl = vocab(DECR('p', 'e', 'a', 'r', 'l'), 1, 0);
+       rug = vocab(DECR('r', 'u', 'g', '\0', '\0'), 1, 0);
+       chain = vocab(DECR('c', 'h', 'a', 'i', 'n'), 1, 0);
+
+       back = vocab(DECR('b', 'a', 'c', 'k', '\0'), 0, 0);
+       look = vocab(DECR('l', 'o', 'o', 'k', '\0'), 0, 0);
+       cave = vocab(DECR('c', 'a', 'v', 'e', '\0'), 0, 0);
+       null = vocab(DECR('n', 'u', 'l', 'l', '\0'), 0, 0);
+       entrance = vocab(DECR('e', 'n', 't', 'r', 'a'), 0, 0);
+       depression = vocab(DECR('d', 'e', 'p', 'r', 'e'), 0, 0);
+       enter = vocab(DECR('e', 'n', 't', 'e', 'r'), 0, 0);
+
+       pour = vocab(DECR('p', 'o', 'u', 'r', '\0'), 2, 0);
+       say = vocab(DECR('s', 'a', 'y', '\0', '\0'), 2, 0);
+       lock = vocab(DECR('l', 'o', 'c', 'k', '\0'), 2, 0);
+       throw = vocab(DECR('t', 'h', 'r', 'o', 'w'), 2, 0);
+       find = vocab(DECR('f', 'i', 'n', 'd', '\0'), 2, 0);
+       invent = vocab(DECR('i', 'n', 'v', 'e', 'n'), 2, 0);
+
+       /* initialize dwarves */
+       chloc = 114;
+       chloc2 = 140;
+       for (i = 1; i <= 6; i++)
+               dseen[i] = FALSE;
+       dflag = 0;
+       dloc[1] = 19;
+       dloc[2] = 27;
+       dloc[3] = 33;
+       dloc[4] = 44;
+       dloc[5] = 64;
+       dloc[6] = chloc;
+       daltloc = 18;
+
+       /* random flags & ctrs */
+       turns = 0;
+       lmwarn = FALSE;
+       iwest = 0;
+       knfloc = 0;
+       detail = 0;
+       abbnum = 5;
+       for (i = 0; i <= 4; i++)
+               if (rtext[2 * i + 81].seekadr != 0)
+                       maxdie = i + 1;
+       numdie = holding = dkill = foobar = bonus = 0;
+       clock1 = 30;
+       clock2 = 50;
+       saved = 0;
+       isclosing = panic = closed = scoring = FALSE;
+}
+
+/* come here if he hits a del */
+void
+trapdel(int n __unused)
+{
+       delhit = 1;             /* main checks, treats as QUIT */
+       signal(SIGINT, trapdel);/* catch subsequent DELs */
+}
+
+
+void
+startup(void)
+{
+       demo = Start();
+       srand((int)time(NULL)); /* random seed */
+#if 0
+       srand(371);             /* non-random seed */
+#endif
+       hinted[3] = yes(65, 1, 0);
+       newloc = 1;
+       delhit = 0;
+       limit = 330;
+       if (hinted[3])
+               limit = 1000;   /* better batteries if instrucs */
+}
diff --git a/games/adventure/io.c b/games/adventure/io.c
new file mode 100644 (file)
index 0000000..eae7695
--- /dev/null
@@ -0,0 +1,610 @@
+/*     $NetBSD: io.c,v 1.22 2009/08/25 06:56:52 dholland Exp $ */
+
+/*-
+ * Copyright (c) 1991, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * The game adventure was originally written in Fortran by Will Crowther
+ * and Don Woods.  It was later translated to C and enhanced by Jim
+ * Gillogly.  This code is derived from software contributed to Berkeley
+ * by Jim Gillogly at The Rand Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)io.c       8.1 (Berkeley) 5/31/93";
+#else
+__RCSID("$NetBSD: io.c,v 1.22 2009/08/25 06:56:52 dholland Exp $");
+#endif
+#endif /* not lint */
+
+/*      Re-coding of advent in C: file i/o and user i/o                 */
+
+#include <err.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "hdr.h"
+#include "extern.h"
+
+static int next(void);
+static void rdesc(int);
+static void rdefault(void);
+static void rhints(void);
+static void rliq(void);
+static void rlocs(void);
+static int rnum(void);
+static void rtrav(void);
+static void rvoc(void);
+
+/* get command from user        */
+/* no prompt, usually           */
+void
+getin(char **wrd1, char **wrd2)
+{
+       char   *s;
+       static char wd1buf[MAXSTR], wd2buf[MAXSTR];
+       int     first, numch, c;
+
+       *wrd1 = wd1buf;                         /* return ptr to internal str */
+       *wrd2 = wd2buf;
+       wd2buf[0] = 0;                          /* in case it isn't set here */
+       for (s = wd1buf, first = 1, numch = 0;;) {
+               c = getchar();
+               if ((*s = (char)c) >= 'A' && *s <= 'Z')
+                       *s = *s - ('A' - 'a');
+               /* convert to upper case */
+               switch (c) {                    /* start reading from user */
+               case '\n':
+                       *s = 0;
+                       return;
+               case ' ':
+                       if (s == wd1buf || s == wd2buf) /* initial blank */
+                               continue;
+                       *s = 0;
+                       if (first) {            /* finished 1st wd; start 2nd */
+                               first = numch = 0;
+                               s = wd2buf;
+                               break;
+                       } else {                /* finished 2nd word */
+                               FLUSHLINE;
+                               *s = 0;
+                               return;
+                       }
+               case EOF:
+                       printf("user closed input stream, quitting...\n");
+                       exit(0);
+               default:
+                       if (++numch >= MAXSTR) {        /* string too long */
+                               printf("Give me a break!!\n");
+                               wd1buf[0] = wd2buf[0] = 0;
+                               FLUSHLINE;
+                               return;
+                       }
+                       s++;
+               }
+       }
+}
+
+/* confirm with rspeak          */
+int
+yes(int x, int y, int z)
+{
+       int     result = TRUE;  /* pacify gcc */
+       int    ch;
+       for (;;) {
+               rspeak(x);      /* tell him what we want */
+               if ((ch = getchar()) == 'y')
+                       result = TRUE;
+               else if (ch == 'n')
+                       result = FALSE;
+               else if (ch == EOF) {
+                       printf("user closed input stream, quitting...\n");
+                       exit(0);
+               }
+               FLUSHLINE;
+               if (ch == 'y' || ch == 'n')
+                       break;
+               printf("Please answer the question.\n");
+       }
+       if (result == TRUE)
+               rspeak(y);
+       if (result == FALSE)
+               rspeak(z);
+       return (result);
+}
+
+/* confirm with mspeak          */
+int
+yesm(int x, int y, int z)
+{
+       int     result = TRUE;  /* pacify gcc */
+       int    ch;
+       for (;;) {
+               mspeak(x);      /* tell him what we want */
+               if ((ch = getchar()) == 'y')
+                       result = TRUE;
+               else if (ch == 'n')
+                       result = FALSE;
+               else if (ch == EOF) {
+                       printf("user closed input stream, quitting...\n");
+                       exit(0);
+               }
+               FLUSHLINE;
+               if (ch == 'y' || ch == 'n')
+                       break;
+               printf("Please answer the question.\n");
+       }
+       if (result == TRUE)
+               mspeak(y);
+       if (result == FALSE)
+               mspeak(z);
+       return (result);
+}
+/* FILE *inbuf,*outbuf; */
+
+static char *inptr;            /* Pointer into virtual disk    */
+
+static int outsw = 0;          /* putting stuff to data file?  */
+
+static const char    iotape[] = "Ax3F'\003tt$8h\315qer*h\017nGKrX\207:!l";
+static const char   *tape = iotape;    /* pointer to encryption tape   */
+
+/* next virtual char, bump adr  */
+static int
+next(void)
+{      
+       int     ch;
+
+       ch = (*inptr ^ random()) & 0xFF;        /* Decrypt input data  */
+       if (outsw) {            /* putting data in tmp file     */
+               if (*tape == 0)
+                       tape = iotape;  /* rewind encryption tape       */
+               *inptr = ch ^ *tape++;  /* re-encrypt and replace value */
+       }
+       inptr++;
+       return (ch);
+}
+
+static char breakch;           /* tell which char ended rnum   */
+
+/* "read" data from virtual file */
+void
+rdata(void)
+{      
+       int     sect;
+       char    ch;
+
+       inptr = data_file;      /* Pointer to virtual data file */
+       srandom(SEED);          /* which is lightly encrypted.  */
+
+       classes = 1;
+       for (;;) {              /* read data sections           */
+               sect = next() - '0';    /* 1st digit of section number  */
+#ifdef VERBOSE
+               printf("Section %c", sect + '0');
+#endif
+               if ((ch = next()) != LF) {      /* is there a second digit?     */
+                       FLUSHLF;
+#ifdef VERBOSE
+                       putchar(ch);
+#endif
+                       sect = 10 * sect + ch - '0';
+               }
+#ifdef VERBOSE
+               putchar('\n');
+#endif
+               switch (sect) {
+               case 0: /* finished reading database    */
+                       return;
+               case 1: /* long form descriptions       */
+                       rdesc(1);
+                       break;
+               case 2: /* short form descriptions      */
+                       rdesc(2);
+                       break;
+               case 3: /* travel table                 */
+                       rtrav();
+                       break;
+               case 4: /* vocabulary                   */
+                       rvoc();
+                       break;
+               case 5: /* object descriptions          */
+                       rdesc(5);
+                       break;
+               case 6: /* arbitrary messages           */
+                       rdesc(6);
+                       break;
+               case 7: /* object locations             */
+                       rlocs();
+                       break;
+               case 8: /* action defaults              */
+                       rdefault();
+                       break;
+               case 9: /* liquid assets                */
+                       rliq();
+                       break;
+               case 10:        /* class messages               */
+                       rdesc(10);
+                       break;
+               case 11:        /* hints                        */
+                       rhints();
+                       break;
+               case 12:        /* magic messages               */
+                       rdesc(12);
+                       break;
+               default:
+                       printf("Invalid data section number: %d\n", sect);
+                       for (;;)
+                               putchar(next());
+               }
+               if (breakch != LF)      /* routines return after "-1"   */
+                       FLUSHLF;
+       }
+}
+
+static char nbf[12];
+
+/* read initial location num    */
+static int
+rnum(void)
+{      
+       char   *s;
+       tape = iotape;          /* restart encryption tape      */
+       for (s = nbf, *s = 0;; s++)
+               if ((*s = next()) == TAB || *s == '\n' || *s == LF)
+                       break;
+       breakch = *s;           /* save char for rtrav()        */
+       *s = 0;                 /* got the number as ascii      */
+       if (nbf[0] == '-')
+               return (-1);    /* end of data                  */
+       return (atoi(nbf));     /* convert it to integer        */
+}
+
+static char *seekhere;
+
+/* read description-format msgs */
+static void
+rdesc(int sect)
+{
+       int     locc;
+       char   *seekstart, *maystart;
+
+       seekhere = inptr;       /* Where are we in virtual file? */
+       outsw = 1;              /* these msgs go into tmp file  */
+       for (oldloc = -1, seekstart = seekhere;;) {
+               maystart = inptr;       /* maybe starting new entry     */
+               if ((locc = rnum()) != oldloc && oldloc >= 0 /* finished msg */
+                   /* unless sect 5 */
+                   && !(sect == 5 && (locc == 0 || locc >= 100))) {
+                       switch (sect) { /* now put it into right table  */
+                       case 1:/* long descriptions            */
+                               ltext[oldloc].seekadr = seekhere;
+                               ltext[oldloc].txtlen = maystart - seekstart;
+                               break;
+                       case 2:/* short descriptions           */
+                               stext[oldloc].seekadr = seekhere;
+                               stext[oldloc].txtlen = maystart - seekstart;
+                               break;
+                       case 5:/* object descriptions          */
+                               ptext[oldloc].seekadr = seekhere;
+                               ptext[oldloc].txtlen = maystart - seekstart;
+                               break;
+                       case 6:/* random messages              */
+                               if (oldloc >= RTXSIZE) 
+                                       errx(1,"Too many random msgs");
+                               rtext[oldloc].seekadr = seekhere;
+                               rtext[oldloc].txtlen = maystart - seekstart;
+                               break;
+                       case 10:        /* class messages               */
+                               ctext[classes].seekadr = seekhere;
+                               ctext[classes].txtlen = maystart - seekstart;
+                               cval[classes++] = oldloc;
+                               break;
+                       case 12:        /* magic messages               */
+                               if (oldloc >= MAGSIZE)
+                                       errx(1,"Too many magic msgs");
+                               mtext[oldloc].seekadr = seekhere;
+                               mtext[oldloc].txtlen = maystart - seekstart;
+                               break;
+                       default:
+                               errx(1,"rdesc called with bad section");
+                       }
+                       seekhere += maystart - seekstart;
+               }
+               if (locc < 0) {
+                       outsw = 0;      /* turn off output              */
+                       seekhere += 3;  /* -1<delimiter>                */
+                       return;
+               }
+               if (sect != 5 || (locc > 0 && locc < 100)) {
+                       if (oldloc != locc)     /* starting a new message */
+                               seekstart = maystart;
+                       oldloc = locc;
+               }
+               FLUSHLF;        /* scan the line                */
+       }
+}
+
+/* read travel table            */
+static void
+rtrav(void)
+{      
+       int     locc;
+       struct travlist *t = NULL;
+       char   *s;
+       char    buf[12];
+       int     len, m, n, entries = 0;
+
+       for (oldloc = -1;;) {   /* get another line             */
+               /* end of entry */              
+               if ((locc = rnum()) != oldloc && oldloc >= 0 && t) {
+                       t->next = 0;    /* terminate the old entry      */
+                       /* printf("%d:%d entries\n",oldloc,entries);       */
+                       /* twrite(oldloc);                                 */
+               }
+               if (locc == -1)
+                       return;
+               if (locc != oldloc) {   /* getting a new entry         */
+                       t = travel[locc] = calloc(1, sizeof(*t));
+                       if (t == NULL)
+                               err(1, NULL);
+                       /* printf("New travel list for %d\n",locc);        */
+                       entries = 0;
+                       oldloc = locc;
+               }
+               for (s = buf;; s++)     /* get the newloc number /ASCII */
+                       if ((*s = next()) == TAB || *s == LF)
+                               break;
+               *s = 0;
+               len = length(buf) - 1;  /* quad long number handling    */
+               /* printf("Newloc: %s (%d chars)\n",buf,len);              */
+               if (len < 4) {  /* no "m" conditions            */
+                       m = 0;
+                       n = atoi(buf);  /* newloc mod 1000 = newloc     */
+               } else {        /* a long integer               */
+                       n = atoi(buf + len - 3);
+                       buf[len - 3] = 0;       /* terminate newloc/1000  */
+                       m = atoi(buf);
+               }
+               while (breakch != LF) { /* only do one line at a time   */
+                       if (t == NULL)
+                               abort();
+                       if (entries++) {
+                               t->next = calloc(1, sizeof(*t));
+                               if (t->next == NULL)
+                                       err(1, NULL);
+                               t = t->next;
+                       }
+                       t->tverb = rnum();      /* get verb from the file */
+                       t->tloc = n;    /* table entry mod 1000         */
+                       t->conditions = m;      /* table entry / 1000   */
+                       /* printf("entry %d for %d\n",entries,locc);    */
+               }
+       }
+}
+#ifdef DEBUG
+
+/* travel options from this loc */
+void
+twrite(int loq)
+{
+       struct travlist *t;
+       printf("If");
+       speak(&ltext[loq]);
+       printf("then\n");
+       for (t = travel[loq]; t != 0; t = t->next) {
+               printf("verb %d takes you to ", t->tverb);
+               if (t->tloc <= 300)
+                       speak(&ltext[t->tloc]);
+               else
+                       if (t->tloc <= 500)
+                               printf("special code %d\n", t->tloc - 300);
+                       else
+                               rspeak(t->tloc - 500);
+               printf("under conditions %d\n", t->conditions);
+       }
+}
+#endif                         /* DEBUG */
+
+/* read the vocabulary          */
+static void
+rvoc(void)
+{
+       char   *s;
+       int     idx;
+       char    buf[6];
+       for (;;) {
+               idx = rnum();
+               if (idx < 0)
+                       break;
+               for (s = buf, *s = 0;; s++)     /* get the word  */
+                       if ((*s = next()) == TAB || *s == '\n' || *s == LF
+                           || *s == ' ')
+                               break;
+               /* terminate word with newline, LF, tab, blank  */
+               if (*s != '\n' && *s != LF)
+                       FLUSHLF;/* can be comments    */
+               *s = 0;
+               /* printf("\"%s\"=%d\n",buf,idx); */
+               vocab(buf, -2, idx);
+       }
+/*     prht(); */
+}
+
+/* initial object locations     */
+static void
+rlocs(void)
+{      
+       for (;;) {
+               if ((obj = rnum()) < 0)
+                       break;
+               plac[obj] = rnum();     /* initial loc for this obj     */
+               if (breakch == TAB)     /* there's another entry        */
+                       fixd[obj] = rnum();
+               else
+                       fixd[obj] = 0;
+       }
+}
+
+/* default verb messages        */
+static void
+rdefault(void)
+{      
+       for (;;) {
+               if ((verb = rnum()) < 0)
+                       break;
+               actspeak[verb] = rnum();
+       }
+}
+
+/* liquid assets &c: cond bits  */
+static void
+rliq(void)
+{      
+       int     bitnum;
+       for (;;) {              /* read new bit list            */
+               if ((bitnum = rnum()) < 0)
+                       break;
+               for (;;) {      /* read locs for bits           */
+                       int n = rnum();
+                       if (n < 0)
+                               break;
+                       cond[n] |= setbit[bitnum];
+                       if (breakch == LF)
+                               break;
+               }
+       }
+}
+
+static void
+rhints(void)
+{
+       int     hintnum, i;
+       hintmax = 0;
+       for (;;) {
+               if ((hintnum = rnum()) < 0)
+                       break;
+               for (i = 1; i < 5; i++)
+                       hints[hintnum][i] = rnum();
+               if (hintnum > hintmax)
+                       hintmax = hintnum;
+       }
+}
+
+
+void
+rspeak(int msg)
+{
+       if (msg != 0)
+               speak(&rtext[msg]);
+}
+
+
+void
+mspeak(int msg)
+{
+       if (msg != 0)
+               speak(&mtext[msg]);
+}
+
+
+/* read, decrypt, and print a message (not ptext)      */
+/* msg is a pointer to seek address and length of mess */
+void
+speak(const struct text *msg)
+{
+       char   *s, nonfirst;
+
+       s = msg->seekadr;
+       nonfirst = 0;
+       while (s - msg->seekadr < msg->txtlen) { /* read a line at a time */
+               tape = iotape;  /* restart decryption tape      */
+               while ((*s++ ^ *tape++) != TAB); /* read past loc num       */
+               /* assume tape is longer than location number           */
+               /* plus the lookahead put together                    */
+               if ((*s ^ *tape) == '>' &&
+                   (*(s + 1) ^ *(tape + 1)) == '$' &&
+                   (*(s + 2) ^ *(tape + 2)) == '<')
+                       break;
+               if (blklin && !nonfirst++)
+                       putchar('\n');
+               do {
+                       if (*tape == 0)
+                               tape = iotape;  /* rewind decryp tape */
+                       putchar(*s ^ *tape);
+               } while ((*s++ ^ *tape++) != LF); /* better end with LF   */
+       }
+}
+
+/* read, decrypt and print a ptext message  */
+/* msg is the number of all the p msgs for this place  */
+/* assumes object 1 doesn't have prop 1, obj 2 no prop 2 &c */
+void
+pspeak(int m, int skip)
+{
+       char   *s, nonfirst;
+       char   *numst;
+       struct text *msg;
+       char   *tbuf;
+
+       msg = &ptext[m];
+       if ((tbuf = (char *) malloc(msg->txtlen + 1)) == NULL)
+               err(1, NULL);
+       memcpy(tbuf, msg->seekadr, msg->txtlen + 1);    /* Room to null */
+       s = tbuf;
+
+       nonfirst = 0;
+       while (s - tbuf < msg->txtlen) {        /* read line at a time */
+               tape = iotape;  /* restart decryption tape      */
+               for (numst = s; (*s ^= *tape++) != TAB; s++); /* get number  */
+
+                               /* Temporarily trash the string (cringe) */
+               *s++ = 0;       /* decrypting number within the string   */
+
+               if (atoi(numst) != 100 * skip && skip >= 0) {
+                       while ((*s++ ^ *tape++) != LF)  /* flush the line    */
+                               if (*tape == 0)
+                                       tape = iotape;
+                       continue;
+               }
+               if ((*s ^ *tape) == '>' && (*(s + 1) ^ *(tape + 1)) == '$' &&
+                   (*(s + 2) ^ *(tape + 2)) == '<')
+                       break;
+               if (blklin && !nonfirst++)
+                       putchar('\n');
+               do {
+                       if (*tape == 0)
+                               tape = iotape;
+                       putchar(*s ^ *tape);
+               } while ((*s++ ^ *tape++) != LF); /* better end with LF   */
+               if (skip < 0)
+                       break;
+       }
+       free(tbuf);
+}
diff --git a/games/adventure/main.c b/games/adventure/main.c
new file mode 100644 (file)
index 0000000..ee30e14
--- /dev/null
@@ -0,0 +1,763 @@
+/*     $NetBSD: main.c,v 1.21 2009/08/25 06:56:52 dholland Exp $       */
+
+/*-
+ * Copyright (c) 1991, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * The game adventure was originally written in Fortran by Will Crowther
+ * and Don Woods.  It was later translated to C and enhanced by Jim
+ * Gillogly.  This code is derived from software contributed to Berkeley
+ * by Jim Gillogly at The Rand Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 1991, 1993\
+ The Regents of the University of California.  All rights reserved.");
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)main.c     8.1 (Berkeley) 6/2/93";
+#else
+__RCSID("$NetBSD: main.c,v 1.21 2009/08/25 06:56:52 dholland Exp $");
+#endif
+#endif /* not lint */
+
+/*      Re-coding of advent in C: main program */
+
+#include <sys/file.h>
+#include <err.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "hdr.h"
+#include "extern.h"
+
+int
+main(int argc, char **argv)
+{
+       int     i;
+       int     rval, ll;
+       struct text *kk;
+
+       /* revoke setgid privileges from dm */
+       setgid(getgid());
+
+       init();         /* Initialize everything */
+       signal(SIGINT, trapdel);
+
+       if (argc > 1) {         /* Restore file specified */
+                               /* Restart is label 8305 (Fortran) */
+               i = restore(argv[1]);   /* See what we've got */
+               switch (i) {
+               case 0: /* The restore worked fine */
+                       yea = Start();
+                       k = null;
+                       unlink(argv[1]);        /* Don't re-use the save */
+                       goto l8;                /* Get where we're going */
+               case 1:                         /* Couldn't open it */
+                       errx(1,"can't open file");      /* So give up */
+               case 2:                         /* Oops -- file was altered */
+                       rspeak(202);            /* You dissolve */
+                       exit(1);        /* File could be non-adventure */
+               }                       /* So don't unlink it. */
+       }
+       startup();                      /* prepare for a user */
+
+       for (;;) {                      /* main command loop (label 2) */
+               if (newloc < 9 && newloc != 0 && isclosing) {
+                       rspeak(130);    /* if closing leave only by */
+                       newloc = loc;   /* main office */
+                       if (!panic)
+                               clock2 = 15;
+                       panic = TRUE;
+               }
+               rval = fdwarf();        /* dwarf stuff */
+               if (rval == 99)
+                       die(99);
+
+l2000:         if (loc == 0)
+                       die(99);        /* label 2000 */
+               kk = &stext[loc];
+               if ((abb[loc] % abbnum) == 0 || kk->seekadr == 0)
+                       kk = &ltext[loc];
+               if (!forced(loc) && dark()) {
+                       if (wasdark && pct(35)) {
+                               die(90);
+                               goto l2000;
+                       }
+                       kk = &rtext[16];
+               }
+#if 0
+l2001:
+#endif
+               if (toting(bear))
+                       rspeak(141);    /* 2001 */
+               speak(kk);
+               k = 1;
+               if (forced(loc))
+                       goto l8;
+               if (loc == 33 && pct(25) && !isclosing)
+                       rspeak(8);
+               if (!dark()) {
+                       abb[loc]++;
+                       for (i = atloc[loc]; i != 0; i = links[i]) { /* 2004 */
+                               obj = i;
+                               if (obj > 100)
+                                       obj -= 100;
+                               if (obj == steps && toting(nugget))
+                                       continue;
+                               if (prop[obj] < 0) {
+                                       if (closed)
+                                               continue;
+                                       prop[obj] = 0;
+                                       if (obj == rug || obj == chain)
+                                               prop[obj] = 1;
+                                       tally--;
+                                       if (tally == tally2 && tally != 0)
+                                               if (limit > 35)
+                                                       limit = 35;
+                               }
+                               ll = prop[obj]; /* 2006 */
+                               if (obj == steps && loc == fixed[steps])
+                                       ll = 1;
+                               pspeak(obj, ll);
+                       }       /* 2008 */
+                       goto l2012;
+       l2009:          k = 54; /* 2009 */
+       l2010:          spk = k;
+       l2011:          rspeak(spk);
+               }
+l2012:         verb = 0;       /* 2012 */
+               obj = 0;
+l2600:         checkhints();   /* to 2600-2602 */
+               if (closed) {
+                       if (prop[oyster] < 0 && toting(oyster))
+                               pspeak(oyster, 1);
+                       for (i = 1; i < 100; i++)
+                               if (toting(i) && prop[i] < 0)   /* 2604 */
+                                       prop[i] = -1 - prop[i];
+               }
+               wasdark = dark();       /* 2605 */
+               if (knfloc > 0 && knfloc != loc)
+                       knfloc = 1;
+               getin(&wd1, &wd2);
+               if (delhit) {   /* user typed a DEL */
+                       delhit = 0;     /* reset counter */
+                       copystr("quit", wd1);   /* pretend he's quitting */
+                       *wd2 = 0;
+               }
+l2608:         if ((foobar = -foobar) > 0)
+                       foobar = 0;     /* 2608 */
+               /* should check here for "magic mode" */
+               turns++;
+               if (demo && turns >= SHORT)
+                       done(1);        /* to 13000 */
+
+               if (verb == say && *wd2 != 0)
+                       verb = 0;
+               if (verb == say)
+                       goto l4090;
+               if (tally == 0 && loc >= 15 && loc != 33)
+                       clock1--;
+               if (clock1 == 0) {
+                       closing();      /* to 10000 */
+                       goto l19999;
+               }
+               if (clock1 < 0)
+                       clock2--;
+               if (clock2 == 0) {
+                       caveclose();    /* to 11000 */
+                       continue;       /* back to 2 */
+               }
+               if (prop[lamp] == 1)
+                       limit--;
+               if (limit <= 30 && here(batter) && prop[batter] == 0
+                   && here(lamp)) {
+                       rspeak(188);    /* 12000 */
+                       prop[batter] = 1;
+                       if (toting(batter))
+                               drop(batter, loc);
+                       limit = limit + 2500;
+                       lmwarn = FALSE;
+                       goto l19999;
+               }
+               if (limit == 0) {
+                       limit = -1;     /* 12400 */
+                       prop[lamp] = 0;
+                       rspeak(184);
+                       goto l19999;
+               }
+               if (limit < 0 && loc <= 8) {
+                       rspeak(185);    /* 12600 */
+                       gaveup = TRUE;
+                       done(2);        /* to 20000 */
+               }
+               if (limit <= 30) {
+                       if (lmwarn || !here(lamp))
+                               goto l19999;    /* 12200 */
+                       lmwarn = TRUE;
+                       spk = 187;
+                       if (place[batter] == 0)
+                               spk = 183;
+                       if (prop[batter] == 1)
+                               spk = 189;
+                       rspeak(spk);
+               }
+l19999:        k = 43;
+               if (liqloc(loc) == water)
+                       k = 70;
+               if (weq(wd1, "enter") &&
+                   (weq(wd2, "strea") || weq(wd2, "water")))
+                       goto l2010;
+               if (weq(wd1, "enter") && *wd2 != 0)
+                       goto l2800;
+               if ((!weq(wd1, "water") && !weq(wd1, "oil"))
+                   || (!weq(wd2, "plant") && !weq(wd2, "door")))
+                       goto l2610;
+               if (at(vocab(wd2, 1, 0)))
+                       copystr("pour", wd2);
+
+l2610:         if (weq(wd1, "west"))
+                       if (++iwest == 10)
+                               rspeak(17);
+l2630:         i = vocab(wd1, -1, 0);
+               if (i == -1) {
+                       spk = 60;       /* 3000 */
+                       if (pct(20))
+                               spk = 61;
+                       if (pct(20))
+                               spk = 13;
+                       rspeak(spk);
+                       goto l2600;
+               }
+               k = i % 1000;
+               kq = i / 1000 + 1;
+               switch (kq) {
+               case 1:
+                       goto l8;
+               case 2:
+                       goto l5000;
+               case 3:
+                       goto l4000;
+               case 4:
+                       goto l2010;
+               default:
+                       bug(22);
+               }
+
+l8:
+               switch (march()) {
+               case 2:
+                       continue;       /* i.e. goto l2 */
+               case 99:
+                       die(99);
+                       goto l2000;
+               default:
+                       bug(110);
+               }
+
+l2800:         copystr(wd2, wd1);
+               *wd2 = 0;
+               goto l2610;
+
+l4000:         verb = k;
+               spk = actspeak[verb];
+               if (*wd2 != 0 && verb != say)
+                       goto l2800;
+               if (verb == say)
+                       obj = *wd2;
+               if (obj != 0)
+                       goto l4090;
+#if 0
+l4080:
+#endif
+               switch (verb) {
+               case 1: /* take = 8010 */
+                       if (atloc[loc] == 0 || links[atloc[loc]] != 0)
+                               goto l8000;
+                       for (i = 1; i <= 5; i++)
+                               if (dloc[i] == loc && dflag >= 2)
+                                       goto l8000;
+                       obj = atloc[loc];
+                       goto l9010;
+               case 2:
+               case 3:
+               case 9: /* 8000 : drop,say,wave */
+               case 10:
+               case 16:
+               case 17:        /* calm,rub,toss */
+               case 19:
+               case 21:
+               case 28:        /* find,feed,break */
+               case 29:        /* wake */
+       l8000:          printf("%s what?\n", wd1);
+                       obj = 0;
+                       goto l2600;
+               case 4:
+               case 6: /* 8040 open,lock */
+                       spk = 28;
+                       if (here(clam))
+                               obj = clam;
+                       if (here(oyster))
+                               obj = oyster;
+                       if (at(door))
+                               obj = door;
+                       if (at(grate))
+                               obj = grate;
+                       if (obj != 0 && here(chain))
+                               goto l8000;
+                       if (here(chain))
+                               obj = chain;
+                       if (obj == 0)
+                               goto l2011;
+                       goto l9040;
+               case 5:
+                       goto l2009;     /* nothing */
+               case 7:
+                       goto l9070;     /* on */
+               case 8:
+                       goto l9080;     /* off */
+               case 11:
+                       goto l8000;     /* walk */
+               case 12:
+                       goto l9120;     /* kill */
+               case 13:
+                       goto l9130;     /* pour */
+               case 14:                /* eat: 8140 */
+                       if (!here(food))
+                               goto l8000;
+       l8142:          destroy(food);
+                       spk = 72;
+                       goto l2011;
+               case 15:
+                       goto l9150;     /* drink */
+               case 18:                /* quit: 8180 */
+                       gaveup = yes(22, 54, 54);
+                       if (gaveup)
+                               done(2);        /* 8185 */
+                       goto l2012;
+               case 20:        /* invent=8200 */
+                       spk = 98;
+                       for (i = 1; i <= 100; i++) {
+                               if (i != bear && toting(i)) {
+                                       if (spk == 98)
+                                               rspeak(99);
+                                       blklin = FALSE;
+                                       pspeak(i, -1);
+                                       blklin = TRUE;
+                                       spk = 0;
+                               }
+                       }
+                       if (toting(bear))
+                               spk = 141;
+                       goto l2011;
+               case 22:
+                       goto l9220;     /* fill */
+               case 23:
+                       goto l9230;     /* blast */
+               case 24:                /* score: 8240 */
+                       scoring = TRUE;
+                       printf("If you were to quit now, you would score");
+                       printf(" %d out of a possible ", score());
+                       printf("%d.", maxscore);
+                       scoring = FALSE;
+                       gaveup = yes(143, 54, 54);
+                       if (gaveup)
+                               done(2);
+                       goto l2012;
+               case 25:        /* foo: 8250 */
+                       k = vocab(wd1, 3, 0);
+                       spk = 42;
+                       if (foobar == 1 - k)
+                               goto l8252;
+                       if (foobar != 0)
+                               spk = 151;
+                       goto l2011;
+       l8252:          foobar = k;
+                       if (k != 4)
+                               goto l2009;
+                       foobar = 0;
+                       if (place[eggs] == plac[eggs]
+                           || (toting(eggs) && loc == plac[eggs]))
+                               goto l2011;
+                       if (place[eggs] == 0 && place[troll] == 0 && 
+                           prop[troll] == 0)
+                               prop[troll] = 1;
+                       k = 2;
+                       if (here(eggs))
+                               k = 1;
+                       if (loc == plac[eggs])
+                               k = 0;
+                       move(eggs, plac[eggs]);
+                       pspeak(eggs, k);
+                       goto l2012;
+               case 26:        /* brief=8260 */
+                       spk = 156;
+                       abbnum = 10000;
+                       detail = 3;
+                       goto l2011;
+               case 27:        /* read=8270 */
+                       if (here(magazine))
+                               obj = magazine;
+                       if (here(tablet))
+                               obj = obj * 100 + tablet;
+                       if (here(message))
+                               obj = obj * 100 + message;
+                       if (closed && toting(oyster))
+                               obj = oyster;
+                       if (obj > 100 || obj == 0 || dark())
+                               goto l8000;
+                       goto l9270;
+               case 30:        /* suspend=8300 */
+                       spk = 201;
+                       if (demo)
+                               goto l2011;
+                       printf("I can suspend your adventure for you so");
+                       printf(" you can resume later, but\n");
+                       printf("you will have to wait at least");
+                       printf(" %d minutes before continuing.", latency);
+                       if (!yes(200, 54, 54))
+                               goto l2012;
+                       datime(&saveday, &savet);
+                       ciao(); /* Do we quit? */
+                       continue;       /* Maybe not */
+               case 31:        /* hours=8310 */
+                       printf("Colossal cave is closed 9am-5pm Mon ");
+                       printf("through Fri except holidays.\n");
+                       goto l2012;
+               default:
+                       bug(23);
+               }
+
+l4090:
+               switch (verb) {
+               case 1: /* take = 9010 */
+       l9010:          switch (trtake()) {
+                       case 2011:
+                               goto l2011;
+                       case 9220:
+                               goto l9220;
+                       case 2009:
+                               goto l2009;
+                       case 2012:
+                               goto l2012;
+                       default:
+                               bug(102);
+                       }
+               l9020: case 2:  /* drop = 9020 */
+                       switch (trdrop()) {
+                       case 2011:
+                               goto l2011;
+                       case 19000:
+                               done(3);
+                       case 2012:
+                               goto l2012;
+                       default:
+                               bug(105);
+                       }
+#if 0
+       l9030:
+#endif
+               case 3:
+                       switch (trsay()) {
+                       case 2012:
+                               goto l2012;
+                       case 2630:
+                               goto l2630;
+                       default:
+                               bug(107);
+                       }
+               l9040: case 4:
+               case 6: /* open, close */
+                       switch (tropen()) {
+                       case 2011:
+                               goto l2011;
+                       case 2010:
+                               goto l2010;
+                       default:
+                               bug(106);
+                       }
+               case 5:
+                       goto l2009;     /* nothing */
+               case 7:                 /* on   9070 */
+       l9070:          if (!here(lamp))
+                               goto l2011;
+                       spk = 184;
+                       if (limit < 0)
+                               goto l2011;
+                       prop[lamp] = 1;
+                       rspeak(39);
+                       if (wasdark)
+                               goto l2000;
+                       goto l2012;
+
+               case 8:         /* off */
+       l9080:          if (!here(lamp))
+                               goto l2011;
+                       prop[lamp] = 0;
+                       rspeak(40);
+                       if (dark())
+                               rspeak(16);
+                       goto l2012;
+
+               case 9: /* wave */
+                       if ((!toting(obj)) && (obj != rod || !toting(rod2)))
+                               spk = 29;
+                       if (obj != rod || !at(fissure) || !toting(obj) || isclosing)
+                               goto l2011;
+                       prop[fissure] = 1 - prop[fissure];
+                       pspeak(fissure, 2 - prop[fissure]);
+                       goto l2012;
+               case 10:
+               case 11:
+               case 18:        /* calm, walk, quit */
+               case 24:
+               case 25:
+               case 26:        /* score, foo, brief */
+               case 30:
+               case 31:        /* suspend, hours */
+                       goto l2011;
+               l9120: case 12:/* kill */
+                       switch (trkill()) {
+                       case 8000:
+                               goto l8000;
+                       case 8:
+                               goto l8;
+                       case 2011:
+                               goto l2011;
+                       case 2608:
+                               goto l2608;
+                       case 19000:
+                               done(3);
+                       default:
+                               bug(112);
+                       }
+               l9130: case 13:/* pour */
+                       if (obj == bottle || obj == 0)
+                               obj = liq();
+                       if (obj == 0)
+                               goto l8000;
+                       if (!toting(obj))
+                               goto l2011;
+                       spk = 78;
+                       if (obj != oil && obj != water)
+                               goto l2011;
+                       prop[bottle] = 1;
+                       place[obj] = 0;
+                       spk = 77;
+                       if (!(at(plant) || at(door)))
+                               goto l2011;
+                       if (at(door)) {
+                               prop[door] = 0; /* 9132 */
+                               if (obj == oil)
+                                       prop[door] = 1;
+                               spk = 113 + prop[door];
+                               goto l2011;
+                       }
+                       spk = 112;
+                       if (obj != water)
+                               goto l2011;
+                       pspeak(plant, prop[plant] + 1);
+                       prop[plant] = (prop[plant] + 2) % 6;
+                       prop[plant2] = prop[plant] / 2;
+                       k = null;
+                       goto l8;
+               case 14:        /* 9140 - eat */
+                       if (obj == food)
+                               goto l8142;
+                       if (obj == bird || obj == snake || obj == clam
+                           || obj == oyster || obj == dwarf || obj == dragon 
+                           || obj == troll || obj == bear)
+                               spk = 71;
+                       goto l2011;
+               l9150: case 15:/* 9150 - drink */
+                       if (obj == 0 && liqloc(loc) != water && (liq() != water
+                           || !here(bottle)))
+                               goto l8000;
+                       if (obj != 0 && obj != water)
+                               spk = 110;
+                       if (spk == 110 || liq() != water || !here(bottle))
+                               goto l2011;
+                       prop[bottle] = 1;
+                       place[water] = 0;
+                       spk = 74;
+                       goto l2011;
+               case 16:        /* 9160: rub */
+                       if (obj != lamp)
+                               spk = 76;
+                       goto l2011;
+               case 17:        /* 9170: throw */
+                       switch (trtoss()) {
+                       case 2011:
+                               goto l2011;
+                       case 9020:
+                               goto l9020;
+                       case 9120:
+                               goto l9120;
+                       case 8:
+                               goto l8;
+                       case 9210:
+                               goto l9210;
+                       default:
+                               bug(113);
+                       }
+               case 19:
+               case 20:        /* 9190: find, invent */
+                       if (at(obj) || (liq() == obj && at(bottle))
+                           || k == liqloc(loc))
+                               spk = 94;
+                       for (i = 1; i <= 5; i++)
+                               if (dloc[i] == loc && dflag >= 2 
+                                   && obj == dwarf)
+                                       spk = 94;
+                       if (closed)
+                               spk = 138;
+                       if (toting(obj))
+                               spk = 24;
+                       goto l2011;
+               l9210: case 21:/* feed */
+                       switch (trfeed()) {
+                       case 2011:
+                               goto l2011;
+                       default:
+                               bug(114);
+                       }
+               l9220: case 22:/* fill */
+                       switch (trfill()) {
+                       case 2011:
+                               goto l2011;
+                       case 8000:
+                               goto l8000;
+                       case 9020:
+                               goto l9020;
+                       default:
+                               bug(115);
+                       }
+               l9230: case 23:/* blast */
+                       if (prop[rod2] < 0 || !closed)
+                               goto l2011;
+                       bonus = 133;
+                       if (loc == 115)
+                               bonus = 134;
+                       if (here(rod2))
+                               bonus = 135;
+                       rspeak(bonus);
+                       done(2);
+               l9270: case 27:/* read */
+                       if (dark())
+                               goto l5190;
+                       if (obj == magazine)
+                               spk = 190;
+                       if (obj == tablet)
+                               spk = 196;
+                       if (obj == message)
+                               spk = 191;
+                       if (obj == oyster && hinted[2] && toting(oyster))
+                               spk = 194;
+                       if (obj != oyster || hinted[2] || !toting(oyster)
+                           || !closed)
+                               goto l2011;
+                       hinted[2] = yes(192, 193, 54);
+                       goto l2012;
+#if 0
+       l9280:
+#endif
+               case 28:        /* break */
+                       if (obj == mirror)
+                               spk = 148;
+                       if (obj == vase && prop[vase] == 0) {
+                               spk = 198;
+                               if (toting(vase))
+                                       drop(vase, loc);
+                               prop[vase] = 2;
+                               fixed[vase] = -1;
+                               goto l2011;
+                       }
+                       if (obj != mirror || !closed)
+                               goto l2011;
+                       rspeak(197);
+                       done(3);
+#if 0
+       l9290:
+#endif
+               case 29:        /* wake */
+                       if (obj != dwarf || !closed)
+                               goto l2011;
+                       rspeak(199);
+                       done(3);
+
+               default:
+                       bug(24);
+               }
+
+l5000:
+               obj = k;
+               if (fixed[k] != loc && !here(k))
+                       goto l5100;
+l5010:         if (*wd2 != 0)
+                       goto l2800;
+               if (verb != 0)
+                       goto l4090;
+               printf("What do you want to do with the %s?\n", wd1);
+               goto l2600;
+l5100:         if (k != grate)
+                       goto l5110;
+               if (loc == 1 || loc == 4 || loc == 7)
+                       k = depression;
+               if (loc > 9 && loc < 15)
+                       k = entrance;
+               if (k != grate)
+                       goto l8;
+l5110:         if (k != dwarf)
+                       goto l5120;
+               for (i = 1; i <= 5; i++)
+                       if (dloc[i] == loc && dflag >= 2)
+                               goto l5010;
+l5120:         if ((liq() == k && here(bottle)) || k == liqloc(loc))
+                       goto l5010;
+               if (obj != plant || !at(plant2) || prop[plant2] == 0)
+                       goto l5130;
+               obj = plant2;
+               goto l5010;
+l5130:         if (obj != knife || knfloc != loc)
+                       goto l5140;
+               knfloc = -1;
+               spk = 116;
+               goto l2011;
+l5140:         if (obj != rod || !here(rod2))
+                       goto l5190;
+               obj = rod2;
+               goto l5010;
+l5190:         if ((verb == find || verb == invent) && *wd2 == 0)
+                       goto l5010;
+               printf("I see no %s here\n", wd1);
+               goto l2012;
+       }
+}
diff --git a/games/adventure/save.c b/games/adventure/save.c
new file mode 100644 (file)
index 0000000..7392c69
--- /dev/null
@@ -0,0 +1,868 @@
+/*     $NetBSD: save.c,v 1.13 2012/01/08 18:16:00 dholland Exp $       */
+
+/*-
+ * Copyright (c) 1991, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * The game adventure was originally written in Fortran by Will Crowther
+ * and Don Woods.  It was later translated to C and enhanced by Jim
+ * Gillogly.  This code is derived from software contributed to Berkeley
+ * by Jim Gillogly at The Rand Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)save.c     8.1 (Berkeley) 5/31/93";
+#else
+__RCSID("$NetBSD: save.c,v 1.13 2012/01/08 18:16:00 dholland Exp $");
+#endif
+#endif                         /* not lint */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <err.h>
+#include <assert.h>
+
+#include "hdr.h"
+#include "extern.h"
+
+struct savefile {
+       FILE *f;
+       const char *name;
+       bool warned;
+       unsigned bintextpos;
+       uint32_t key;
+       struct crcstate crc;
+       unsigned char pad[8];
+       unsigned padpos;
+};
+
+#define BINTEXT_WIDTH 60
+#define FORMAT_VERSION 2
+#define FORMAT_VERSION_NOSUM 1
+static const char header[] = "Adventure save file\n";
+
+////////////////////////////////////////////////////////////
+// base16 output encoding
+
+/*
+ * Map 16 plain values into 90 coded values and back.
+ */
+
+static const char coding[90] =
+       "Db.GOyT]7a6zpF(c*5H9oK~0[WVAg&kR)ml,2^q-1Y3v+"
+       "X/=JirZL$C>_N?:}B{dfnsxU<@MQ%8|P!4h`ESt;euwIj"
+;
+
+static int
+readletter(char letter, unsigned char *ret)
+{
+       const char *s;
+
+       s = strchr(coding, letter);
+       if (s == NULL) {
+               return 1;
+       }
+       *ret = (s - coding) % 16;
+       return 0;
+}
+
+static char
+writeletter(unsigned char nibble)
+{
+       unsigned code;
+
+       assert(nibble < 16);
+       do {
+               code = (16 * (random() % 6)) + nibble;
+       } while (code >= 90);
+       return coding[code];
+}
+
+////////////////////////////////////////////////////////////
+// savefile
+
+/*
+ * Open a savefile.
+ */
+static struct savefile *
+savefile_open(const char *name, bool forwrite)
+{
+       struct savefile *sf;
+
+       sf = malloc(sizeof(*sf));
+       if (sf == NULL) {
+               return NULL;
+       }
+       sf->f = fopen(name, forwrite ? "w" : "r");
+       if (sf->f == NULL) {
+               free(sf);
+               fprintf(stderr,
+                   "Hmm.  The name \"%s\" appears to be magically blocked.\n",
+                   name);
+               return NULL;
+       }
+       sf->name = name;
+       sf->warned = false;
+       sf->bintextpos = 0;
+       sf->key = 0;
+       crc_start(&sf->crc);
+       memset(sf->pad, 0, sizeof(sf->pad));
+       sf->padpos = 0;
+       return sf;
+}
+
+/*
+ * Raw read.
+ */
+static int
+savefile_rawread(struct savefile *sf, void *data, size_t len)
+{
+       size_t result;
+
+       result = fread(data, 1, len, sf->f);
+       if (result != len || ferror(sf->f)) {
+               fprintf(stderr, "Oops: error reading %s.\n", sf->name);
+               sf->warned = true;
+               return 1;
+       }
+       return 0;
+}
+
+/*
+ * Raw write.
+ */
+static int
+savefile_rawwrite(struct savefile *sf, const void *data, size_t len)
+{
+       size_t result;
+
+       result = fwrite(data, 1, len, sf->f);
+       if (result != len || ferror(sf->f)) {
+               fprintf(stderr, "Oops: error writing %s.\n", sf->name);
+               sf->warned = true;
+               return 1;
+       }
+       return 0;
+}
+
+/*
+ * Close a savefile.
+ */
+static int
+savefile_close(struct savefile *sf)
+{
+       int ret;
+
+       if (sf->bintextpos > 0) {
+               savefile_rawwrite(sf, "\n", 1);
+       }
+
+       ret = 0;
+       if (fclose(sf->f)) {
+               if (!sf->warned) {
+                       fprintf(stderr, "Oops: error on %s.\n", sf->name);
+               }
+               ret = 1;
+       }
+       free(sf);
+       return ret;
+}
+
+/*
+ * Read encoded binary data, discarding any whitespace that appears.
+ */
+static int
+savefile_bintextread(struct savefile *sf, void *data, size_t len)
+{
+       size_t pos;
+       unsigned char *udata;
+       int ch;
+
+       udata = data;
+       pos = 0;
+       while (pos < len) {
+               ch = fgetc(sf->f);
+               if (ch == EOF || ferror(sf->f)) {
+                       fprintf(stderr, "Oops: error reading %s.\n", sf->name);
+                       sf->warned = true;
+                       return 1;
+               }
+               if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') {
+                       continue;
+               }
+               udata[pos++] = ch;
+       }
+       return 0;
+}
+
+/*
+ * Read binary data, decoding from text using readletter().
+ */
+static int
+savefile_binread(struct savefile *sf, void *data, size_t len)
+{
+       unsigned char buf[64];
+       unsigned char *udata;
+       unsigned char val1, val2;
+       size_t pos, amt, i;
+
+       udata = data;
+       pos = 0;
+       while (pos < len) {
+               amt = len - pos;
+               if (amt > sizeof(buf) / 2) {
+                       amt = sizeof(buf) / 2;
+               }
+               if (savefile_bintextread(sf, buf, amt*2)) {
+                       return 1;
+               }
+               for (i=0; i<amt; i++) {
+                       if (readletter(buf[i*2], &val1)) {
+                               return 1;
+                       }
+                       if (readletter(buf[i*2 + 1], &val2)) {
+                               return 1;
+                       }
+                       udata[pos++] = val1 * 16 + val2;
+               }
+       }
+       return 0;
+}
+
+/*
+ * Write encoded binary data, inserting newlines to get a neatly
+ * formatted block.
+ */
+static int
+savefile_bintextwrite(struct savefile *sf, const void *data, size_t len)
+{
+       size_t pos, amt;
+       const unsigned char *udata;
+
+       udata = data;
+       pos = 0;
+       while (pos < len) {
+               amt = BINTEXT_WIDTH - sf->bintextpos;
+               if (amt > len - pos) {
+                       amt = len - pos;
+               }
+               if (savefile_rawwrite(sf, udata + pos, amt)) {
+                       return 1;
+               }
+               pos += amt;
+               sf->bintextpos += amt;
+               if (sf->bintextpos >= BINTEXT_WIDTH) {
+                       savefile_rawwrite(sf, "\n", 1);
+                       sf->bintextpos = 0;
+               }
+       }
+       return 0;
+}
+
+/*
+ * Write binary data, encoding as text using writeletter().
+ */
+static int
+savefile_binwrite(struct savefile *sf, const void *data, size_t len)
+{
+       unsigned char buf[64];
+       const unsigned char *udata;
+       size_t pos, bpos;
+       unsigned char byte;
+
+       udata = data;
+       pos = 0;
+       bpos = 0;
+       while (pos < len) {
+               byte = udata[pos++];
+               buf[bpos++] = writeletter(byte >> 4);
+               buf[bpos++] = writeletter(byte & 0xf);
+               if (bpos >= sizeof(buf)) {
+                       if (savefile_bintextwrite(sf, buf, bpos)) {
+                               return 1;
+                       }
+                       bpos = 0;
+               }
+       }
+       if (savefile_bintextwrite(sf, buf, bpos)) {
+               return 1;
+       }
+       return 0;
+}
+
+/*
+ * Lightweight "encryption" for save files. This is not meant to
+ * be secure and wouldn't be even if we didn't write the decrypt
+ * key to the beginning of the save file; it's just meant to be
+ * enough to discourage casual cheating.
+ */
+
+/*
+ * Make cheesy hash of buf[0..buflen]. Note: buf and outhash may overlap.
+ */
+static void
+hash(const void *data, size_t datalen, unsigned char *out, size_t outlen)
+{
+       const unsigned char *udata;
+       size_t i;
+       uint64_t val;
+       const unsigned char *uval;
+       size_t valpos;
+
+       udata = data;
+       val = 0;
+       for (i=0; i<datalen; i++) {
+               val = val ^ 0xbadc0ffee;
+               val = (val << 4) | (val >> 60);
+               val += udata[i] ^ 0xbeef;
+       }
+
+       uval = (unsigned char *)&val;
+       valpos = 0;
+       for (i=0; i<outlen; i++) {
+               out[i] = uval[valpos++];
+               if (valpos >= sizeof(val)) {
+                       valpos = 0;
+               }
+       }
+}
+
+/*
+ * Set the "encryption" key.
+ */
+static void
+savefile_key(struct savefile *sf, uint32_t key)
+{
+       sf->key = 0;
+       crc_start(&sf->crc);
+       hash(&sf->key, sizeof(sf->key), sf->pad, sizeof(sf->pad));
+       sf->padpos = 0;
+}
+
+/*
+ * Get an "encryption" pad byte. This forms a stream "cipher" that we
+ * xor with the plaintext save data.
+ */
+static unsigned char
+savefile_getpad(struct savefile *sf)
+{
+       unsigned char ret;
+
+       ret = sf->pad[sf->padpos++];
+       if (sf->padpos >= sizeof(sf->pad)) {
+               hash(sf->pad, sizeof(sf->pad), sf->pad, sizeof(sf->pad));
+               sf->padpos = 0;
+       }
+       return ret;
+}
+
+/*
+ * Read "encrypted" data.
+ */
+static int
+savefile_cread(struct savefile *sf, void *data, size_t len)
+{
+       char buf[64];
+       unsigned char *udata;
+       size_t pos, amt, i;
+       unsigned char ch;
+
+       udata = data;
+       pos = 0;
+       while (pos < len) {
+               amt = len - pos;
+               if (amt > sizeof(buf)) {
+                       amt = sizeof(buf);
+               }
+               if (savefile_binread(sf, buf, amt)) {
+                       return 1;
+               }
+               for (i=0; i<amt; i++) {
+                       ch = buf[i];
+                       ch ^= savefile_getpad(sf);
+                       udata[pos + i] = ch;
+               }
+               pos += amt;
+       }
+       crc_add(&sf->crc, data, len);
+       return 0;
+}
+
+/*
+ * Write "encrypted" data.
+ */
+static int
+savefile_cwrite(struct savefile *sf, const void *data, size_t len)
+{
+       char buf[64];
+       const unsigned char *udata;
+       size_t pos, amt, i;
+       unsigned char ch;
+
+       udata = data;
+       pos = 0;
+       while (pos < len) {
+               amt = len - pos;
+               if (amt > sizeof(buf)) {
+                       amt = sizeof(buf);
+               }
+               for (i=0; i<amt; i++) {
+                       ch = udata[pos + i];
+                       ch ^= savefile_getpad(sf);
+                       buf[i] = ch;
+               }
+               if (savefile_binwrite(sf, buf, amt)) {
+                       return 1;
+               }
+               pos += amt;
+       }
+       crc_add(&sf->crc, data, len);
+       return 0;
+}
+
+////////////////////////////////////////////////////////////
+// compat for old save files
+
+struct compat_saveinfo {
+       void   *address;
+       int     width;
+};
+
+static const struct compat_saveinfo compat_savearray[] =
+{
+       {&abbnum, sizeof(abbnum)},
+       {&attack, sizeof(attack)},
+       {&blklin, sizeof(blklin)},
+       {&bonus, sizeof(bonus)},
+       {&chloc, sizeof(chloc)},
+       {&chloc2, sizeof(chloc2)},
+       {&clock1, sizeof(clock1)},
+       {&clock2, sizeof(clock2)},
+       {&closed, sizeof(closed)},
+       {&isclosing, sizeof(isclosing)},
+       {&daltloc, sizeof(daltloc)},
+       {&demo, sizeof(demo)},
+       {&detail, sizeof(detail)},
+       {&dflag, sizeof(dflag)},
+       {&dkill, sizeof(dkill)},
+       {&dtotal, sizeof(dtotal)},
+       {&foobar, sizeof(foobar)},
+       {&gaveup, sizeof(gaveup)},
+       {&holding, sizeof(holding)},
+       {&iwest, sizeof(iwest)},
+       {&k, sizeof(k)},
+       {&k2, sizeof(k2)},
+       {&knfloc, sizeof(knfloc)},
+       {&kq, sizeof(kq)},
+       {&latency, sizeof(latency)},
+       {&limit, sizeof(limit)},
+       {&lmwarn, sizeof(lmwarn)},
+       {&loc, sizeof(loc)},
+       {&maxdie, sizeof(maxdie)},
+       {&maxscore, sizeof(maxscore)},
+       {&newloc, sizeof(newloc)},
+       {&numdie, sizeof(numdie)},
+       {&obj, sizeof(obj)},
+       {&oldloc2, sizeof(oldloc2)},
+       {&oldloc, sizeof(oldloc)},
+       {&panic, sizeof(panic)},
+       {&saveday, sizeof(saveday)},
+       {&savet, sizeof(savet)},
+       {&scoring, sizeof(scoring)},
+       {&spk, sizeof(spk)},
+       {&stick, sizeof(stick)},
+       {&tally, sizeof(tally)},
+       {&tally2, sizeof(tally2)},
+       {&tkk, sizeof(tkk)},
+       {&turns, sizeof(turns)},
+       {&verb, sizeof(verb)},
+       {&wd1, sizeof(wd1)},
+       {&wd2, sizeof(wd2)},
+       {&wasdark, sizeof(wasdark)},
+       {&yea, sizeof(yea)},
+       {atloc, sizeof(atloc)},
+       {dloc, sizeof(dloc)},
+       {dseen, sizeof(dseen)},
+       {fixed, sizeof(fixed)},
+       {hinted, sizeof(hinted)},
+       {links, sizeof(links)},
+       {odloc, sizeof(odloc)},
+       {place, sizeof(place)},
+       {prop, sizeof(prop)},
+       {tk, sizeof(tk)},
+
+       {NULL, 0}
+};
+
+static int
+compat_restore(const char *infile)
+{
+       FILE   *in;
+       const struct compat_saveinfo *p;
+       char   *s;
+       long    sum, cksum = 0;
+       int     i;
+       struct crcstate crc;
+
+       if ((in = fopen(infile, "rb")) == NULL) {
+               fprintf(stderr,
+                   "Hmm.  The file \"%s\" appears to be magically blocked.\n",
+                   infile);
+               return 1;
+       }
+       fread(&sum, sizeof(sum), 1, in);        /* Get the seed */
+       srandom((int) sum);
+       for (p = compat_savearray; p->address != NULL; p++) {
+               fread(p->address, p->width, 1, in);
+               for (s = p->address, i = 0; i < p->width; i++, s++)
+                       *s = (*s ^ random()) & 0xFF;    /* Lightly decrypt */
+       }
+       fclose(in);
+
+       crc_start(&crc);                /* See if she cheated */
+       for (p = compat_savearray; p->address != NULL; p++)
+               crc_add(&crc, p->address, p->width);
+       cksum = crc_get(&crc);
+       if (sum != cksum)       /* Tsk tsk */
+               return 2;       /* Altered the file */
+       /* We successfully restored, so this really was a save file */
+
+       /*
+        * The above code loads these from disk even though they're
+        * pointers. Null them out and hope we don't crash on them
+        * later; that's better than having them be garbage.
+        */
+       tkk = NULL;
+       wd1 = NULL;
+       wd2 = NULL;
+
+       return 0;
+}
+
+////////////////////////////////////////////////////////////
+// save + restore
+
+static int *const save_ints[] = {
+       &abbnum,
+       &attack,
+       &blklin,
+       &bonus,
+       &chloc,
+       &chloc2,
+       &clock1,
+       &clock2,
+       &closed,
+       &isclosing,
+       &daltloc,
+       &demo,
+       &detail,
+       &dflag,
+       &dkill,
+       &dtotal,
+       &foobar,
+       &gaveup,
+       &holding,
+       &iwest,
+       &k,
+       &k2,
+       &knfloc,
+       &kq,
+       &latency,
+       &limit,
+       &lmwarn,
+       &loc,
+       &maxdie,
+       &maxscore,
+       &newloc,
+       &numdie,
+       &obj,
+       &oldloc2,
+       &oldloc,
+       &panic,
+       &saveday,
+       &savet,
+       &scoring,
+       &spk,
+       &stick,
+       &tally,
+       &tally2,
+       &turns,
+       &verb,
+       &wasdark,
+       &yea,
+};
+static const unsigned num_save_ints = __arraycount(save_ints);
+
+#define INTARRAY(sym) { sym, __arraycount(sym) }
+
+static const struct {
+       int *ptr;
+       unsigned num;
+} save_intarrays[] = {
+       INTARRAY(atloc),
+       INTARRAY(dseen),
+       INTARRAY(dloc),
+       INTARRAY(odloc),
+       INTARRAY(fixed),
+       INTARRAY(hinted),
+       INTARRAY(links),
+       INTARRAY(place),
+       INTARRAY(prop),
+       INTARRAY(tk),
+};
+static const unsigned num_save_intarrays = __arraycount(save_intarrays);
+
+#undef INTARRAY
+
+#if 0
+static const struct {
+       void *ptr;
+       size_t len;
+} save_blobs[] = {
+       { &wd1, sizeof(wd1) },
+       { &wd2, sizeof(wd2) },
+       { &tkk, sizeof(tkk) },
+};
+static const unsigned num_save_blobs = __arraycount(save_blobs);
+#endif
+
+/*
+ * Write out a save file. Returns nonzero on error.
+ */
+int
+save(const char *outfile)
+{
+       struct savefile *sf;
+       struct timespec now;
+       uint32_t key, writeable_key;
+       uint32_t version;
+       unsigned i, j, n;
+       uint32_t val, sum;
+
+       sf = savefile_open(outfile, true);
+       if (sf == NULL) {
+               return 1;
+       }
+
+       if (savefile_rawwrite(sf, header, strlen(header))) {
+               savefile_close(sf);
+               return 1;
+       }
+
+       version = htonl(FORMAT_VERSION);
+       if (savefile_binwrite(sf, &version, sizeof(version))) {
+               savefile_close(sf);
+               return 1;
+       }
+
+       clock_gettime(CLOCK_REALTIME, &now);
+       key = (uint32_t)(now.tv_sec & 0xffffffff) ^ (uint32_t)(now.tv_nsec);
+
+       writeable_key = htonl(key);
+       if (savefile_binwrite(sf, &writeable_key, sizeof(writeable_key))) {
+               savefile_close(sf);
+               return 1;
+       }
+
+       /* other parts of the code may depend on us doing this here */
+       srandom(key);
+
+       savefile_key(sf, key);
+
+       /*
+        * Integers
+        */
+       for (i=0; i<num_save_ints; i++) {
+               val = *(save_ints[i]);
+               val = htonl(val);
+               if (savefile_cwrite(sf, &val, sizeof(val))) {
+                       savefile_close(sf);
+                       return 1;
+               }
+       }
+
+       /*
+        * Arrays of integers
+        */
+       for (i=0; i<num_save_intarrays; i++) {
+               n = save_intarrays[i].num;
+               for (j=0; j<n; j++) {
+                       val = save_intarrays[i].ptr[j];
+                       val = htonl(val);
+                       if (savefile_cwrite(sf, &val, sizeof(val))) {
+                               savefile_close(sf);
+                               return 1;
+                       }
+               }
+       }
+
+#if 0
+       /*
+        * Blobs
+        */
+       for (i=0; i<num_save_blobs; i++) {
+               if (savefile_cwrite(sf, save_blobs[i].ptr, save_blobs[i].len)) {
+                       savefile_close(sf);
+                       return 1;
+               }
+       }
+#endif
+
+       sum = htonl(crc_get(&sf->crc));
+       if (savefile_binwrite(sf, &sum, sizeof(&sum))) {
+               savefile_close(sf);
+               return 1;
+       }
+       savefile_close(sf);
+       return 0;
+}
+
+/*
+ * Read in a save file. Returns nonzero on error.
+ */
+int
+restore(const char *infile)
+{
+       struct savefile *sf;
+       char buf[sizeof(header)];
+       size_t headersize = strlen(header);
+       uint32_t version, key, sum;
+       unsigned i, j, n;
+       uint32_t val;
+       bool skipsum = false;
+
+       sf = savefile_open(infile, false);
+       if (sf == NULL) {
+               return 1;
+       }
+
+       if (savefile_rawread(sf, buf, headersize)) {
+               savefile_close(sf);
+               return 1;
+       }
+       buf[headersize] = 0;
+       if (strcmp(buf, header) != 0) {
+               savefile_close(sf);
+               fprintf(stderr, "Oh dear, that isn't one of my save files.\n");
+               fprintf(stderr,
+                   "Trying the Olde Waye; this myte notte Worke.\n");
+               return compat_restore(infile);
+       }
+
+       if (savefile_binread(sf, &version, sizeof(version))) {
+               savefile_close(sf);
+               return 1;
+       }
+       version = ntohl(version);
+       switch (version) {
+           case FORMAT_VERSION:
+               break;
+           case FORMAT_VERSION_NOSUM:
+               skipsum = true;
+               break;
+           default:
+               savefile_close(sf);
+               fprintf(stderr,
+                   "Oh dear, that file must be from the future. I don't know"
+                   " how to read it!\n");
+               return 1;
+       }
+
+       if (savefile_binread(sf, &key, sizeof(key))) {
+               savefile_close(sf);
+               return 1;
+       }
+       key = ntohl(key);
+       savefile_key(sf, key);
+
+       /* other parts of the code may depend on us doing this here */
+       srandom(key);
+
+       /*
+        * Integers
+        */
+       for (i=0; i<num_save_ints; i++) {
+               if (savefile_cread(sf, &val, sizeof(val))) {
+                       savefile_close(sf);
+                       return 1;
+               }
+               val = ntohl(val);
+               *(save_ints[i]) = val;
+       }
+
+       /*
+        * Arrays of integers
+        */
+       for (i=0; i<num_save_intarrays; i++) {
+               n = save_intarrays[i].num;
+               for (j=0; j<n; j++) {
+                       if (savefile_cread(sf, &val, sizeof(val))) {
+                               savefile_close(sf);
+                               return 1;
+                       }
+                       val = ntohl(val);
+                       save_intarrays[i].ptr[j] = val;
+               }
+       }
+
+#if 0
+       /*
+        * Blobs
+        */
+       for (i=0; i<num_save_blobs; i++) {
+               if (savefile_cread(sf, save_blobs[i].ptr, save_blobs[i].len)) {
+                       savefile_close(sf);
+                       return 1;
+               }
+       }
+#endif
+
+       if (savefile_binread(sf, &sum, sizeof(&sum))) {
+               savefile_close(sf);
+               return 1;
+       }
+       sum = ntohl(sum);
+       /* See if she cheated */
+       if (!skipsum && sum != crc_get(&sf->crc)) {
+               /* Tsk tsk, altered the file */
+               savefile_close(sf);
+               return 2;
+       }
+       savefile_close(sf);
+
+       /* Load theoretically invalidates these */
+       tkk = NULL;
+       wd1 = NULL;
+       wd2 = NULL;
+
+       return 0;
+}
diff --git a/games/adventure/setup.c b/games/adventure/setup.c
new file mode 100644 (file)
index 0000000..36a7c0e
--- /dev/null
@@ -0,0 +1,128 @@
+/* $NetBSD: setup.c,v 1.11 2005/07/01 00:03:36 jmc Exp $ */
+
+/*-
+ * Copyright (c) 1991, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Jim Gillogly at The Rand Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] = "@(#) Copyright (c) 1991, 1993\n\
+       The Regents of the University of California.  All rights reserved.\n";
+
+#if 0
+static char sccsid[] = "@(#)setup.c    8.1 (Berkeley) 5/31/93";
+#else
+static char rcsid[] = "$NetBSD: setup.c,v 1.11 2005/07/01 00:03:36 jmc Exp $";
+#endif
+#endif                         /* not lint */
+
+/*
+ * Setup: keep the structure of the original Adventure port, but use an
+ * internal copy of the data file, serving as a sort of virtual disk.  It's
+ * lightly encrypted to prevent casual snooping of the executable.
+ *
+ * Also do appropriate things to tabs so that bogus editors will do the right
+ * thing with the data file.
+ *
+ */
+
+#define SIG1 " *      Jim Gillogly"
+#define SIG2 " *      Sterday, 6 Thrimidge S.R. 1993, 15:24"
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include "hdr.h"       /* SEED lives in there; keep them coordinated. */
+
+#define USAGE "Usage: setup file > data.c (file is typically glorkz)\n"
+
+#define YES 1
+#define NO  0
+
+#define LINE 10                        /* How many values do we get on a line? */
+
+int main(int, char *[]);
+
+int
+main(int argc, char *argv[])
+{
+       FILE   *infile;
+       int     c, count, linestart;
+
+       if (argc != 2) {
+               fprintf(stderr, USAGE);
+               exit(1);
+       }
+
+       if ((infile = fopen(argv[1], "r")) == NULL) {
+               fprintf(stderr, "Can't read file %s: %s\n", argv[1],
+                   strerror(errno));
+               exit(1);
+       }
+       puts("/*\n * data.c: created by setup from the ascii data file.");
+       puts(SIG1);
+       puts(SIG2);
+       puts(" */");
+       printf("\n\nchar data_file[] =\n{");
+       srandom(SEED);
+       count = 0;
+       linestart = YES;
+
+       while ((c = getc(infile)) != EOF) {
+               if (linestart && c == ' ') { /* Convert first spaces to tab */
+                       printf("0x%02x,", 
+                           (unsigned int)('\t' ^ random()) & 0xFF);
+                       while ((c = getc(infile)) == ' ' && c != EOF);
+                       /* Drop the non-whitespace character through */
+                       linestart = NO;
+               }
+               switch (c) {
+               case '\t':
+                       linestart = NO; /* Don't need to convert spaces */
+                       break;
+               case '\n':
+                       linestart = YES;        /* Ready to convert spaces
+                                                * again */
+                       break;
+               }
+               if (count++ % LINE == 0)        /* Finished a line? */
+                       printf("\n\t");
+               printf("0x%02x,", (unsigned int)(c ^ random()) & 0xFF);
+       }
+       puts("\n\t0\n};");
+       fclose(infile);
+       fflush(stdout);
+       if (ferror(stdout)) {
+               perror("error writing standard output");
+               exit(1);
+       }
+       exit(0);
+}
diff --git a/games/adventure/subr.c b/games/adventure/subr.c
new file mode 100644 (file)
index 0000000..0fd6c27
--- /dev/null
@@ -0,0 +1,1057 @@
+/*     $NetBSD: subr.c,v 1.13 2009/08/25 06:56:52 dholland Exp $       */
+
+/*-
+ * Copyright (c) 1991, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * The game adventure was originally written in Fortran by Will Crowther
+ * and Don Woods.  It was later translated to C and enhanced by Jim
+ * Gillogly.  This code is derived from software contributed to Berkeley
+ * by Jim Gillogly at The Rand Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)subr.c     8.1 (Berkeley) 5/31/93";
+#else
+__RCSID("$NetBSD: subr.c,v 1.13 2009/08/25 06:56:52 dholland Exp $");
+#endif
+#endif                         /* not lint */
+
+/*      Re-coding of advent in C: subroutines from main                 */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "hdr.h"
+#include "extern.h"
+
+static void badmove(void);
+static int bitset(int, int);
+static int dropper(void);
+static int liq2(int);
+static int mback(void);
+static int specials(void);
+static int trbridge(void);
+
+/*              Statement functions     */
+int
+toting(int objj)
+{
+       if (place[objj] == -1)
+               return (TRUE);
+       else
+               return (FALSE);
+}
+
+int
+here(int objj)
+{
+       if (place[objj] == loc || toting(objj))
+               return (TRUE);
+       else
+               return (FALSE);
+}
+
+int
+at(int objj)
+{
+       if (place[objj] == loc || fixed[objj] == loc)
+               return (TRUE);
+       else
+               return (FALSE);
+}
+
+static int
+liq2(int pbotl)
+{
+       return ((1 - pbotl) * water + (pbotl / 2) * (water + oil));
+}
+
+int
+liq(void)
+{
+       int     i;
+       i = prop[bottle];
+       if (i > -1 - i)
+               return (liq2(i));
+       else
+               return (liq2(-1 - i));
+}
+
+/* may want to clean this one up a bit */
+int
+liqloc(int locc)
+{
+       int     i, j, l;
+       i = cond[locc] / 2;
+       j = ((i * 2) % 8) - 5;
+       l = cond[locc] / 4;
+       l = l % 2;
+       return (liq2(j * l + 1));
+}
+
+static int
+bitset(int l, int n)
+{
+       if (cond[l] & setbit[n])
+               return (TRUE);
+       return (FALSE);
+}
+
+int
+forced(int locc)
+{
+       if (cond[locc] == 2)
+               return (TRUE);
+       return (FALSE);
+}
+
+int
+dark(void)
+{
+       if ((cond[loc] % 2) == 0 && (prop[lamp] == 0 || !here(lamp)))
+               return (TRUE);
+       return (FALSE);
+}
+
+int
+pct(int n)
+{
+       if (ran(100) < n)
+               return (TRUE);
+       return (FALSE);
+}
+
+
+int
+fdwarf(void)
+{                              /* 71 */
+       int     i, j;
+       struct travlist *kk;
+
+       if (newloc != loc && !forced(loc) && !bitset(loc, 3)) {
+               for (i = 1; i <= 5; i++) {
+                       if (odloc[i] != newloc || !dseen[i])
+                               continue;
+                       newloc = loc;
+                       rspeak(2);
+                       break;
+               }
+       }
+       loc = newloc;           /* 74 */
+       if (loc == 0 || forced(loc) || bitset(newloc, 3))
+               return (2000);
+       if (dflag == 0) {
+               if (loc >= 15)
+                       dflag = 1;
+               return (2000);
+       }
+       if (dflag == 1) {       /* 6000 */
+               if (loc < 15 || pct(95))
+                       return (2000);
+               dflag = 2;
+               for (i = 1; i <= 2; i++) {
+                       j = 1 + ran(5);
+                       if (pct(50) && saved == -1)
+                               dloc[j] = 0;    /* 6001 */
+               }
+               for (i = 1; i <= 5; i++) {
+                       if (dloc[i] == loc)
+                               dloc[i] = daltloc;
+                       odloc[i] = dloc[i];     /* 6002 */
+               }
+               rspeak(3);
+               drop(axe, loc);
+               return (2000);
+       }
+       dtotal = attack = stick = 0;    /* 6010 */
+       for (i = 1; i <= 6; i++) {      /* loop to 6030 */
+               if (dloc[i] == 0)
+                       continue;
+               j = 1;
+               for (kk = travel[dloc[i]]; kk != 0; kk = kk->next) {
+                       newloc = kk->tloc;
+                       if (newloc > 300 || newloc < 15 || newloc == odloc[i]
+                           || (j > 1 && newloc == tk[j - 1]) || j >= 20
+                           || newloc == dloc[i] || forced(newloc)
+                           || (i == 6 && bitset(newloc, 3))
+                           || kk->conditions == 100)
+                               continue;
+                       tk[j++] = newloc;
+               }
+               tk[j] = odloc[i];       /* 6016 */
+               if (j >= 2)
+                       j--;
+               j = 1 + ran(j);
+               odloc[i] = dloc[i];
+               dloc[i] = tk[j];
+               dseen[i] = (dseen[i] && loc >= 15) || 
+                   (dloc[i] == loc || odloc[i] == loc);
+               if (!dseen[i])
+                       continue;       /* i.e. goto 6030 */
+               dloc[i] = loc;
+               if (i == 6) {   /* pirate's spotted him */
+                       if (loc == chloc || prop[chest] >= 0)
+                               continue;
+                       k = 0;
+                       for (j = 50; j <= maxtrs; j++) { /* loop to 6020 */
+                               if (j == pyramid && (loc == plac[pyramid]
+                                       || loc == plac[emerald]))
+                                       goto l6020;
+                               if (toting(j))
+                                       goto l6022;
+               l6020:          if (here(j))
+                                       k = 1;
+                       }       /* 6020 */
+                       if (tally == tally2 + 1 && k == 0 && place[chest] == 0
+                           && here(lamp) && prop[lamp] == 1)
+                               goto l6025;
+                       if (odloc[6] != dloc[6] && pct(20))
+                               rspeak(127);
+                       continue;       /* to 6030 */
+       l6022:          rspeak(128);
+                       if (place[message] == 0)
+                               move(chest, chloc);
+                       move(message, chloc2);
+                       for (j = 50; j <= maxtrs; j++) { /* loop to 6023 */
+                               if (j == pyramid && (loc == plac[pyramid]
+                                       || loc == plac[emerald]))
+                                       continue;
+                               if (at(j) && fixed[j] == 0)
+                                       carry(j, loc);
+                               if (toting(j))
+                                       drop(j, chloc);
+                       }
+       l6024:          dloc[6] = odloc[6] = chloc;
+                       dseen[6] = FALSE;
+                       continue;
+       l6025:          rspeak(186);
+                       move(chest, chloc);
+                       move(message, chloc2);
+                       goto l6024;
+               }
+               dtotal++;       /* 6027 */
+               if (odloc[i] != dloc[i])
+                       continue;
+               attack++;
+               if (knfloc >= 0)
+                       knfloc = loc;
+               if (ran(1000) < 95 * (dflag - 2))
+                       stick++;
+       }                       /* 6030 */
+       if (dtotal == 0)
+               return (2000);
+       if (dtotal != 1) {
+               printf("There are %d threatening little dwarves ", dtotal);
+               printf("in the room with you.\n");
+       } else
+               rspeak(4);
+       if (attack == 0)
+               return (2000);
+       if (dflag == 2)
+               dflag = 3;
+       if (saved != -1)
+               dflag = 20;
+       if (attack != 1) {
+               printf("%d of them throw knives at you!\n", attack);
+               k = 6;
+l82:           if (stick <= 1) {       /* 82 */
+                       rspeak(k + stick);
+                       if (stick == 0)
+                               return (2000);
+               } else
+                       printf("%d of them get you!\n", stick); /* 83 */
+               oldloc2 = loc;
+               return (99);
+       }
+       rspeak(5);
+       k = 52;
+       goto l82;
+}
+
+
+/* label 8              */
+int
+march(void)
+{      
+       int     ll1, ll2;
+
+       if ((tkk = travel[newloc = loc]) == 0)
+               bug(26);
+       if (k == null)
+               return (2);
+       if (k == cave) {        /* 40                   */
+               if (loc < 8)
+                       rspeak(57);
+               if (loc >= 8)
+                       rspeak(58);
+               return (2);
+       }
+       if (k == look) {        /* 30                   */
+               if (detail++ < 3)
+                       rspeak(15);
+               wasdark = FALSE;
+               abb[loc] = 0;
+               return (2);
+       }
+       if (k == back) {        /* 20                   */
+               switch (mback()) {
+               case 2:
+                       return (2);
+               case 9:
+                       goto l9;
+               default:
+                       bug(100);
+               }
+       }
+       oldloc2 = oldloc;
+       oldloc = loc;
+l9:
+       for (; tkk != 0; tkk = tkk->next)
+               if (tkk->tverb == 1 || tkk->tverb == k)
+                       break;
+       if (tkk == 0) {
+               badmove();
+               return (2);
+       }
+l11:   ll1 = tkk->conditions;  /* 11                   */
+       ll2 = tkk->tloc;
+       newloc = ll1;           /* newloc=conditions    */
+       k = newloc % 100;       /* k used for prob      */
+       if (newloc <= 300) {
+               if (newloc <= 100) {    /* 13                   */
+                       if (newloc != 0 && !pct(newloc))
+                               goto l12;       /* 14   */
+       l16:            newloc = ll2;   /* newloc=location      */
+                       if (newloc <= 300)
+                               return (2);
+                       if (newloc <= 500)
+                               switch (specials()) {   /* to 30000           */
+                               case 2:
+                                       return (2);
+                               case 12:
+                                       goto l12;
+                               case 99:
+                                       return (99);
+                               default:
+                                       bug(101);
+                               }
+                       rspeak(newloc - 500);
+                       newloc = loc;
+                       return (2);
+               }
+               if (toting(k) || (newloc > 200 && at(k)))
+                       goto l16;
+               goto l12;
+       }
+       if (prop[k] != (newloc / 100) - 3)
+               goto l16;       /* newloc still conditions */
+l12:                           /* alternative to probability move      */
+       for (; tkk != 0; tkk = tkk->next)
+               if (tkk->tloc != ll2 || tkk->conditions != ll1)
+                       break;
+       if (tkk == 0)
+               bug(25);
+       goto l11;
+}
+
+/* 20                   */
+static int
+mback(void)
+{      
+       struct travlist *tk2, *j;
+       int     ll;
+       if (forced(k = oldloc))
+               k = oldloc2;    /* k=location           */
+       oldloc2 = oldloc;
+       oldloc = loc;
+       tk2 = 0;
+       if (k == loc) {
+               rspeak(91);
+               return (2);
+       }
+       for (; tkk != 0; tkk = tkk->next) {     /* 21                   */
+               ll = tkk->tloc;
+               if (ll == k) {
+                       k = tkk->tverb; /* k back to verb       */
+                       tkk = travel[loc];
+                       return (9);
+               }
+               if (ll <= 300) {
+                       j = travel[loc];
+                       if (forced(ll) && k == j->tloc)
+                               tk2 = tkk;
+               }
+       }
+       tkk = tk2;              /* 23                   */
+       if (tkk != 0) {
+               k = tkk->tverb;
+               tkk = travel[loc];
+               return (9);
+       }
+       rspeak(140);
+       return (2);
+}
+
+/* 30000                */
+static int
+specials(void)
+{      
+       switch (newloc -= 300) {
+               case 1:         /* 30100                */
+               newloc = 99 + 100 - loc;
+               if (holding == 0 || (holding == 1 && toting(emerald)))
+                       return (2);
+               newloc = loc;
+               rspeak(117);
+               return (2);
+       case 2:         /* 30200                */
+               drop(emerald, loc);
+               return (12);
+       case 3:         /* to 30300             */
+               return (trbridge());
+       default:
+               bug(29);
+       }
+}
+
+/* 30300                */
+static int
+trbridge(void)
+{
+       if (prop[troll] == 1) {
+               pspeak(troll, 1);
+               prop[troll] = 0;
+               move(troll2, 0);
+               move(troll2 + 100, 0);
+               move(troll, plac[troll]);
+               move(troll + 100, fixd[troll]);
+               juggle(chasm);
+               newloc = loc;
+               return (2);
+       }
+       newloc = plac[troll] + fixd[troll] - loc;       /* 30310    */
+       if (prop[troll] == 0)
+               prop[troll] = 1;
+       if (!toting(bear))
+               return (2);
+       rspeak(162);
+       prop[chasm] = 1;
+       prop[troll] = 2;
+       drop(bear, newloc);
+       fixed[bear] = -1;
+       prop[bear] = 3;
+       if (prop[spices] < 0)
+               tally2++;
+       oldloc2 = newloc;
+       return (99);
+}
+
+/* 20                   */
+static void
+badmove(void)
+{
+       spk = 12;
+       if (k >= 43 && k <= 50)
+               spk = 9;
+       if (k == 29 || k == 30)
+               spk = 9;
+       if (k == 7 || k == 36 || k == 37)
+               spk = 10;
+       if (k == 11 || k == 19)
+               spk = 11;
+       if (verb == find || verb == invent)
+               spk = 59;
+       if (k == 62 || k == 65)
+               spk = 42;
+       if (k == 17)
+               spk = 80;
+       rspeak(spk);
+}
+
+void
+bug(int n)
+{
+       printf("Please tell jim@rand.org that fatal bug %d happened.\n", n);
+       exit(1);
+}
+
+/* 2600 &c              */
+void
+checkhints(void)
+{      
+       int     hint;
+       for (hint = 4; hint <= hintmax; hint++) {
+               if (hinted[hint])
+                       continue;
+               if (!bitset(loc, hint))
+                       hintlc[hint] = -1;
+               hintlc[hint]++;
+               if (hintlc[hint] < hints[hint][1])
+                       continue;
+               switch (hint) {
+               case 4: /* 40400 */
+                       if (prop[grate] == 0 && !here(keys))
+                               goto l40010;
+                       goto l40020;
+               case 5: /* 40500 */
+                       if (here(bird) && toting(rod) && obj == bird)
+                               goto l40010;
+                       continue;       /* i.e. goto l40030 */
+               case 6: /* 40600 */
+                       if (here(snake) && !here(bird))
+                               goto l40010;
+                       goto l40020;
+               case 7: /* 40700 */
+                       if (atloc[loc] == 0 && atloc[oldloc] == 0
+                           && atloc[oldloc2] == 0 && holding > 1)
+                               goto l40010;
+                       goto l40020;
+               case 8: /* 40800 */
+                       if (prop[emerald] != -1 && prop[pyramid] == -1)
+                               goto l40010;
+                       goto l40020;
+               case 9:
+                       goto l40010;    /* 40900 */
+               default:
+                       bug(27);
+               }
+l40010:        hintlc[hint] = 0;
+               if (!yes(hints[hint][3], 0, 54))
+                       continue;
+               printf("I am prepared to give you a hint, but it will ");
+               printf("cost you %d points.\n", hints[hint][2]);
+               hinted[hint] = yes(175, hints[hint][4], 54);
+l40020:        hintlc[hint] = 0;
+       }
+}
+
+/* 9030                 */
+int
+trsay(void)
+{
+       int     i;
+       if (*wd2 != 0)
+               copystr(wd2, wd1);
+       i = vocab(wd1, -1, 0);
+       if (i == 62 || i == 65 || i == 71 || i == 2025) {
+               *wd2 = 0;
+               obj = 0;
+               return (2630);
+       }
+       printf("\nOkay, \"%s\".\n", wd2);
+       return (2012);
+}
+
+/* 9010                 */
+int
+trtake(void)
+{      
+       if (toting(obj))
+               return (2011);  /* 9010 */
+       spk = 25;
+       if (obj == plant && prop[plant] <= 0)
+               spk = 115;
+       if (obj == bear && prop[bear] == 1)
+               spk = 169;
+       if (obj == chain && prop[bear] != 0)
+               spk = 170;
+       if (fixed[obj] != 0)
+               return (2011);
+       if (obj == water || obj == oil) {
+               if (here(bottle) && liq() == obj) {
+                       obj = bottle;
+                       goto l9017;
+               }
+               obj = bottle;
+               if (toting(bottle) && prop[bottle] == 1)
+                       return (9220);
+               if (prop[bottle] != 1)
+                       spk = 105;
+               if (!toting(bottle))
+                       spk = 104;
+               return (2011);
+       }
+l9017: if (holding >= 7) {
+               rspeak(92);
+               return (2012);
+       }
+       if (obj == bird) {
+               if (prop[bird] != 0)
+                       goto l9014;
+               if (toting(rod)) {
+                       rspeak(26);
+                       return (2012);
+               }
+               if (!toting(cage)) {    /* 9013 */
+                       rspeak(27);
+                       return (2012);
+               }
+               prop[bird] = 1; /* 9015 */
+       }
+l9014: if ((obj == bird || obj == cage) && prop[bird] != 0)
+               carry(bird + cage - obj, loc);
+       carry(obj, loc);
+       k = liq();
+       if (obj == bottle && k != 0)
+               place[k] = -1;
+       return (2009);
+}
+
+/* 9021                 */
+static int
+dropper(void)
+{      
+       k = liq();
+       if (k == obj)
+               obj = bottle;
+       if (obj == bottle && k != 0)
+               place[k] = 0;
+       if (obj == cage && prop[bird] != 0)
+               drop(bird, loc);
+       if (obj == bird)
+               prop[bird] = 0;
+       drop(obj, loc);
+       return (2012);
+}
+
+/* 9020                 */
+int
+trdrop(void)
+{
+       if (toting(rod2) && obj == rod && !toting(rod))
+               obj = rod2;
+       if (!toting(obj))
+               return (2011);
+       if (obj == bird && here(snake)) {
+               rspeak(30);
+               if (closed)
+                       return (19000);
+               destroy(snake);
+               prop[snake] = 1;
+               return (dropper());
+       }
+       if (obj == coins && here(vend)) {       /* 9024                 */
+               destroy(coins);
+               drop(batter, loc);
+               pspeak(batter, 0);
+               return (2012);
+       }
+       if (obj == bird && at(dragon) && prop[dragon] == 0) {   /* 9025 */
+               rspeak(154);
+               destroy(bird);
+               prop[bird] = 0;
+               if (place[snake] == plac[snake])
+                       tally2--;
+               return (2012);
+       }
+       if (obj == bear && at(troll)) { /* 9026                 */
+               rspeak(163);
+               move(troll, 0);
+               move(troll + 100, 0);
+               move(troll2, plac[troll]);
+               move(troll2 + 100, fixd[troll]);
+               juggle(chasm);
+               prop[troll] = 2;
+               return (dropper());
+       }
+       if (obj != vase || loc == plac[pillow]) { /* 9027       */
+               rspeak(54);
+               return (dropper());
+       }
+       prop[vase] = 2;         /* 9028                 */
+       if (at(pillow))
+               prop[vase] = 0;
+       pspeak(vase, prop[vase] + 1);
+       if (prop[vase] != 0)
+               fixed[vase] = -1;
+       return (dropper());
+}
+
+/* 9040                 */
+int
+tropen(void)
+{
+       if (obj == clam || obj == oyster) {
+               k = 0;          /* 9046                 */
+               if (obj == oyster)
+                       k = 1;
+               spk = 124 + k;
+               if (toting(obj))
+                       spk = 120 + k;
+               if (!toting(trident))
+                       spk = 122 + k;
+               if (verb == lock)
+                       spk = 61;
+               if (spk != 124)
+                       return (2011);
+               destroy(clam);
+               drop(oyster, loc);
+               drop(pearl, 105);
+               return (2011);
+       }
+       if (obj == door)
+               spk = 111;
+       if (obj == door && prop[door] == 1)
+               spk = 54;
+       if (obj == cage)
+               spk = 32;
+       if (obj == keys)
+               spk = 55;
+       if (obj == grate || obj == chain)
+               spk = 31;
+       if (spk != 31 || !here(keys))
+               return (2011);
+       if (obj == chain) {
+               if (verb == lock) {
+                       spk = 172;      /* 9049: lock           */
+                       if (prop[chain] != 0)
+                               spk = 34;
+                       if (loc != plac[chain])
+                               spk = 173;
+                       if (spk != 172)
+                               return (2011);
+                       prop[chain] = 2;
+                       if (toting(chain))
+                               drop(chain, loc);
+                       fixed[chain] = -1;
+                       return (2011);
+               }
+               spk = 171;
+               if (prop[bear] == 0)
+                       spk = 41;
+               if (prop[chain] == 0)
+                       spk = 37;
+               if (spk != 171)
+                       return (2011);
+               prop[chain] = 0;
+               fixed[chain] = 0;
+               if (prop[bear] != 3)
+                       prop[bear] = 2;
+               fixed[bear] = 2 - prop[bear];
+               return (2011);
+       }
+       if (isclosing) {
+               k = 130;
+               if (!panic)
+                       clock2 = 15;
+               panic = TRUE;
+               return (2010);
+       }
+       k = 34 + prop[grate];   /* 9043                 */
+       prop[grate] = 1;
+       if (verb == lock)
+               prop[grate] = 0;
+       k = k + 2 * prop[grate];
+       return (2010);
+}
+
+/* 9120                         */
+int
+trkill(void)
+{      
+       int     i;
+       for (i = 1; i <= 5; i++)
+               if (dloc[i] == loc && dflag >= 2)
+                       break;
+       if (i == 6)
+               i = 0;
+       if (obj == 0) {         /* 9122                         */
+               if (i != 0)
+                       obj = dwarf;
+               if (here(snake))
+                       obj = obj * 100 + snake;
+               if (at(dragon) && prop[dragon] == 0)
+                       obj = obj * 100 + dragon;
+               if (at(troll))
+                       obj = obj * 100 + troll;
+               if (here(bear) && prop[bear] == 0)
+                       obj = obj * 100 + bear;
+               if (obj > 100)
+                       return (8000);
+               if (obj == 0) {
+                       if (here(bird) && verb != throw)
+                               obj = bird;
+                       if (here(clam) || here(oyster))
+                               obj = 100 * obj + clam;
+                       if (obj > 100)
+                               return (8000);
+               }
+       }
+       if (obj == bird) {      /* 9124                         */
+               spk = 137;
+               if (closed)
+                       return (2011);
+               destroy(bird);
+               prop[bird] = 0;
+               if (place[snake] == plac[snake])
+                       tally2++;
+               spk = 45;
+       }
+       if (obj == 0)
+               spk = 44;       /* 9125                         */
+       if (obj == clam || obj == oyster)
+               spk = 150;
+       if (obj == snake)
+               spk = 46;
+       if (obj == dwarf)
+               spk = 49;
+       if (obj == dwarf && closed)
+               return (19000);
+       if (obj == dragon)
+               spk = 147;
+       if (obj == troll)
+               spk = 157;
+       if (obj == bear)
+               spk = 165 + (prop[bear] + 1) / 2;
+       if (obj != dragon || prop[dragon] != 0)
+               return (2011);
+       rspeak(49);
+       verb = 0;
+       obj = 0;
+       getin(&wd1, &wd2);
+       if (!weq(wd1, "y") && !weq(wd1, "yes"))
+               return (2608);
+       pspeak(dragon, 1);
+       prop[dragon] = 2;
+       prop[rug] = 0;
+       k = (plac[dragon] + fixd[dragon]) / 2;
+       move(dragon + 100, -1);
+       move(rug + 100, 0);
+       move(dragon, k);
+       move(rug, k);
+       for (obj = 1; obj <= 100; obj++)
+               if (place[obj] == plac[dragon] || place[obj] == fixd[dragon])
+                       move(obj, k);
+       loc = k;
+       k = null;
+       return (8);
+}
+
+/* 9170: throw                  */
+int
+trtoss(void)
+{      
+       int     i;
+       if (toting(rod2) && obj == rod && !toting(rod))
+               obj = rod2;
+       if (!toting(obj))
+               return (2011);
+       if (obj >= 50 && obj <= maxtrs && at(troll)) {
+               spk = 159;      /* 9178                 */
+               drop(obj, 0);
+               move(troll, 0);
+               move(troll + 100, 0);
+               drop(troll2, plac[troll]);
+               drop(troll2 + 100, fixd[troll]);
+               juggle(chasm);
+               return (2011);
+       }
+       if (obj == food && here(bear)) {
+               obj = bear;     /* 9177                 */
+               return (9210);
+       }
+       if (obj != axe)
+               return (9020);
+       for (i = 1; i <= 5; i++) {
+               if (dloc[i] == loc) {
+                       spk = 48;       /* 9172                 */
+                       if (ran(3) == 0 || saved != -1)
+       l9175:          {
+                               rspeak(spk);
+                               drop(axe, loc);
+                               k = null;
+                               return (8);
+                       }
+                       dseen[i] = FALSE;
+                       dloc[i] = 0;
+                       spk = 47;
+                       dkill++;
+                       if (dkill == 1)
+                               spk = 149;
+                       goto l9175;
+               }
+       }
+       spk = 152;
+       if (at(dragon) && prop[dragon] == 0)
+               goto l9175;
+       spk = 158;
+       if (at(troll))
+               goto l9175;
+       if (here(bear) && prop[bear] == 0) {
+               spk = 164;
+               drop(axe, loc);
+               fixed[axe] = -1;
+               prop[axe] = 1;
+               juggle(bear);
+               return (2011);
+       }
+       obj = 0;
+       return (9120);
+}
+
+/* 9210                 */
+int
+trfeed(void)
+{      
+       if (obj == bird) {
+               spk = 100;
+               return (2011);
+       }
+       if (obj == snake || obj == dragon || obj == troll) {
+               spk = 102;
+               if (obj == dragon && prop[dragon] != 0)
+                       spk = 110;
+               if (obj == troll)
+                       spk = 182;
+               if (obj != snake || closed || !here(bird))
+                       return (2011);
+               spk = 101;
+               destroy(bird);
+               prop[bird] = 0;
+               tally2++;
+               return (2011);
+       }
+       if (obj == dwarf) {
+               if (!here(food))
+                       return (2011);
+               spk = 103;
+               dflag++;
+               return (2011);
+       }
+       if (obj == bear) {
+               if (prop[bear] == 0)
+                       spk = 102;
+               if (prop[bear] == 3)
+                       spk = 110;
+               if (!here(food))
+                       return (2011);
+               destroy(food);
+               prop[bear] = 1;
+               fixed[axe] = 0;
+               prop[axe] = 0;
+               spk = 168;
+               return (2011);
+       }
+       spk = 14;
+       return (2011);
+}
+
+/* 9220 */
+int
+trfill(void)
+{
+       if (obj == vase) {
+               spk = 29;
+               if (liqloc(loc) == 0)
+                       spk = 144;
+               if (liqloc(loc) == 0 || !toting(vase))
+                       return (2011);
+               rspeak(145);
+               prop[vase] = 2;
+               fixed[vase] = -1;
+               return (9020);  /* advent/10 goes to 9024 */
+       }
+       if (obj != 0 && obj != bottle)
+               return (2011);
+       if (obj == 0 && !here(bottle))
+               return (8000);
+       spk = 107;
+       if (liqloc(loc) == 0)
+               spk = 106;
+       if (liq() != 0)
+               spk = 105;
+       if (spk != 107)
+               return (2011);
+       prop[bottle] = ((cond[loc] % 4) / 2) * 2;
+       k = liq();
+       if (toting(bottle))
+               place[k] = -1;
+       if (k == oil)
+               spk = 108;
+       return (2011);
+}
+
+/* 10000 */
+void
+closing(void)
+{      
+       int     i;
+
+       prop[grate] = prop[fissure] = 0;
+       for (i = 1; i <= 6; i++) {
+               dseen[i] = FALSE;
+               dloc[i] = 0;
+       }
+       move(troll, 0);
+       move(troll + 100, 0);
+       move(troll2, plac[troll]);
+       move(troll2 + 100, fixd[troll]);
+       juggle(chasm);
+       if (prop[bear] != 3)
+               destroy(bear);
+       prop[chain] = 0;
+       fixed[chain] = 0;
+       prop[axe] = 0;
+       fixed[axe] = 0;
+       rspeak(129);
+       clock1 = -1;
+       isclosing = TRUE;
+}
+
+/* 11000 */
+void
+caveclose(void)
+{      
+       int     i;
+       prop[bottle] = put(bottle, 115, 1);
+       prop[plant] = put(plant, 115, 0);
+       prop[oyster] = put(oyster, 115, 0);
+       prop[lamp] = put(lamp, 115, 0);
+       prop[rod] = put(rod, 115, 0);
+       prop[dwarf] = put(dwarf, 115, 0);
+       loc = 115;
+       oldloc = 115;
+       newloc = 115;
+
+       put(grate, 116, 0);
+       prop[snake] = put(snake, 116, 1);
+       prop[bird] = put(bird, 116, 1);
+       prop[cage] = put(cage, 116, 0);
+       prop[rod2] = put(rod2, 116, 0);
+       prop[pillow] = put(pillow, 116, 0);
+
+       prop[mirror] = put(mirror, 115, 0);
+       fixed[mirror] = 116;
+
+       for (i = 1; i <= 100; i++)
+               if (toting(i))
+                       destroy(i);
+       rspeak(132);
+       closed = TRUE;
+}
diff --git a/games/adventure/vocab.c b/games/adventure/vocab.c
new file mode 100644 (file)
index 0000000..1a1b700
--- /dev/null
@@ -0,0 +1,218 @@
+/*     $NetBSD: vocab.c,v 1.15 2009/08/25 06:56:52 dholland Exp $      */
+
+/*-
+ * Copyright (c) 1991, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * The game adventure was originally written in Fortran by Will Crowther
+ * and Don Woods.  It was later translated to C and enhanced by Jim
+ * Gillogly.  This code is derived from software contributed to Berkeley
+ * by Jim Gillogly at The Rand Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)vocab.c    8.1 (Berkeley) 5/31/93";
+#else
+__RCSID("$NetBSD: vocab.c,v 1.15 2009/08/25 06:56:52 dholland Exp $");
+#endif
+#endif                         /* not lint */
+
+/*      Re-coding of advent in C: data structure routines               */
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "hdr.h"
+#include "extern.h"
+
+void
+destroy(int object)
+{
+       move(object, 0);
+}
+
+void
+juggle(int object)
+{
+       int     i, j;
+
+       i = place[object];
+       j = fixed[object];
+       move(object, i);
+       move(object + 100, j);
+}
+
+void
+move(int object, int where)
+{
+       int     from;
+
+       if (object <= 100)
+               from = place[object];
+       else
+               from = fixed[object - 100];
+       if (from > 0 && from <= 300)
+               carry(object, from);
+       drop(object, where);
+}
+
+int
+put(int object, int where, int pval)
+{
+       move(object, where);
+       return (-1 - pval);
+}
+
+void
+carry(int object, int where)
+{
+       int     temp;
+
+       if (object <= 100) {
+               if (place[object] == -1)
+                       return;
+               place[object] = -1;
+               holding++;
+       }
+       if (atloc[where] == object) {
+               atloc[where] = links[object];
+               return;
+       }
+       for (temp = atloc[where]; links[temp] != object; temp = links[temp]);
+       links[temp] = links[object];
+}
+
+
+void
+drop(int object, int where)
+{
+       if (object > 100)
+               fixed[object - 100] = where;
+       else {
+               if (place[object] == -1)
+                       holding--;
+               place[object] = where;
+       }
+       if (where <= 0)
+               return;
+       links[object] = atloc[where];
+       atloc[where] = object;
+}
+
+/* look up or store a word      */
+/* -2 for store, -1 for user word, >=0 for canned lookup */
+/* used for storing only        */
+int
+vocab(const char *word, int type, int value)
+{
+       int     adr;
+       const char *s;
+       char   *t;
+       int     hash, i;
+       struct hashtab *h;
+
+       for (hash = 0, s = word, i = 0; i < 5 && *s; i++) /* some kind of hash*/
+               hash += *s++;   /* add all chars in the word    */
+       hash = (hash * 3719) & 077777;  /* pulled that one out of a hat */
+       hash %= HTSIZE;         /* put it into range of table   */
+
+       for (adr = hash;; adr++) {      /* look for entry in table      */
+               if (adr == HTSIZE)
+                       adr = 0;/* wrap around                  */
+               h = &voc[adr];  /* point at the entry           */
+               switch (type) {
+               case -2:        /* fill in entry                */
+                       if (h->val)     /* already got an entry?        */
+                               goto exitloop2;
+                       h->val = value;
+                       h->atab = malloc(length(word));
+                       if (h->atab == NULL)
+                               err(1, NULL);
+                       for (s = word, t = h->atab; *s;)
+                               *t++ = *s++ ^ '=';
+                       *t = 0 ^ '=';
+                       /* encrypt slightly to thwart core reader       */
+                       /* printf("Stored \"%s\" (%d ch) as entry %d\n",   */
+                       /* word, length(word), adr);               */
+                       return (0);     /* entry unused                 */
+               case -1:        /* looking up user word         */
+                       if (h->val == 0)
+                               return (-1);    /* not found    */
+                       for (s = word, t = h->atab; *t ^ '=';)
+                               if ((*s++ ^ '=') != *t++)
+                                       goto exitloop2;
+                       if ((*s ^ '=') != *t && s - word < 5)
+                               goto exitloop2;
+                       /* the word matched o.k.                        */
+                       return (h->val);
+               default:        /* looking up known word        */
+                       if (h->val == 0)
+                               errx(1,"Unable to find %s in vocab", word);
+                       for (s = word, t = h->atab; *t ^ '=';)
+                               if ((*s++ ^ '=') != *t++)
+                                       goto exitloop2;
+                       /* the word matched o.k.                        */
+                       if (h->val / 1000 != type)
+                               continue;
+                       return (h->val % 1000);
+               }
+
+exitloop2:                     /* hashed entry does not match  */
+               if (adr + 1 == hash || hash == 0)
+                       errx(1,"Hash table overflow");
+       }
+}
+
+/* print hash table (for debugging)             */
+static __unused void
+prht(void)
+{      
+       int     i, j, l;
+       char   *c;
+       struct hashtab *h;
+       for (i = 0; i < HTSIZE / 10 + 1; i++) {
+               printf("%4d", i * 10);
+               for (j = 0; j < 10; j++) {
+                       if (i * 10 + j >= HTSIZE)
+                               break;
+                       h = &voc[i * 10 + j];
+                       putchar(' ');
+                       if (h->val == 0) {
+                               printf("-----");
+                               continue;
+                       }
+                       for (l = 0, c = h->atab; l < 5; l++)
+                               if ((*c ^ '='))
+                                       putchar(*c++ ^ '=');
+                               else
+                                       putchar(' ');
+               }
+               putchar('\n');
+       }
+}
diff --git a/games/adventure/wizard.c b/games/adventure/wizard.c
new file mode 100644 (file)
index 0000000..152915a
--- /dev/null
@@ -0,0 +1,162 @@
+/*     $NetBSD: wizard.c,v 1.16 2012/10/12 15:41:10 dholland Exp $     */
+
+/*-
+ * Copyright (c) 1991, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * The game adventure was originally written in Fortran by Will Crowther
+ * and Don Woods.  It was later translated to C and enhanced by Jim
+ * Gillogly.  This code is derived from software contributed to Berkeley
+ * by Jim Gillogly at The Rand Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)wizard.c   8.1 (Berkeley) 6/2/93";
+#else
+__RCSID("$NetBSD: wizard.c,v 1.16 2012/10/12 15:41:10 dholland Exp $");
+#endif
+#endif                         /* not lint */
+
+/*      Re-coding of advent in C: privileged operations                 */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include "hdr.h"
+#include "extern.h"
+
+static int wizard(void);
+
+void
+datime(int *d, int *t)
+{
+       time_t  tvec;
+       struct tm *tptr;
+
+       time(&tvec);
+       tptr = localtime(&tvec);
+       /* day since 1977  (mod leap)   */
+       *d = (tptr->tm_yday + 365 * (tptr->tm_year - 77)
+             + (tptr->tm_year - 77) / 4 - (tptr->tm_year - 1) / 100
+             + (tptr->tm_year + 299) / 400);
+       /* bug: this will overflow in the year 2066 AD (with 16 bit int) */
+       /* it will be attributed to Wm the C's millenial celebration    */
+       /* and minutes since midnite */
+       *t = tptr->tm_hour * 60 + tptr->tm_min;
+}                              /* pretty painless              */
+
+
+static char magic[6];
+
+void
+poof(void)
+{
+       strcpy(magic, DECR('d', 'w', 'a', 'r', 'f'));
+       latency = 45;
+}
+
+int
+Start(void)
+{
+       int     d, t, delay;
+
+       datime(&d, &t);
+       delay = (d - saveday) * 1440 + (t - savet);     /* good for about a
+                                                        * month     */
+
+       if (delay >= latency) {
+               saved = -1;
+               return (FALSE);
+       }
+       printf("This adventure was suspended a mere %d minute%s ago.",
+           delay, delay == 1 ? "" : "s");
+       if (delay <= latency / 3) {
+               mspeak(2);
+               exit(0);
+       }
+       mspeak(8);
+       if (!wizard()) {
+               mspeak(9);
+               exit(0);
+       }
+       saved = -1;
+       return (FALSE);
+}
+
+/* not as complex as advent/10 (for now)        */
+static int
+wizard(void)
+{      
+       char   *word, *x;
+       if (!yesm(16, 0, 7))
+               return (FALSE);
+       mspeak(17);
+       getin(&word, &x);
+       if (!weq(word, magic)) {
+               mspeak(20);
+               return (FALSE);
+       }
+       mspeak(19);
+       return (TRUE);
+}
+
+void
+ciao(void)
+{
+       char fname[80];
+       size_t pos;
+
+       printf("What would you like to call the saved version?\n");
+       /* XXX - should use fgetln to avoid arbitrary limit */
+       for (pos = 0; pos < sizeof(fname) - 1; pos++) {
+               int ch;
+               ch = getchar();
+               if (ch == '\n' || ch == EOF)
+                       break;
+               fname[pos] = ch;
+       }
+       fname[pos] = '\0';
+       if (save(fname) != 0)
+               return;         /* Save failed */
+       printf("To resume, say \"adventure %s\".\n", fname);
+       printf("\"With these rooms I might now have been familiarly ");
+       printf("acquainted.\"\n");
+       exit(0);
+}
+
+
+int
+ran(int range)
+{
+       long    i;
+
+       i = rand() % range;
+       return (i);
+}
index 74478c986b80c51a5eca08129927c3413cfc4933..db19bb0ddbe8441a4d2ed7f748ce21b5916417b3 100644 (file)
@@ -68,6 +68,9 @@
 2013/12/1 12:00:00,external/mit/Makefile
 2013/12/1 12:00:00,external/public-domain
 2013/12/1 12:00:00,external/README
+2013/12/1 12:00:00,games/adventure
+2013/12/1 12:00:00,games/Makefile
+2013/12/1 12:00:00,games/Makefile.inc
 2013/12/1 12:00:00,gnu/dist/texinfo
 2013/12/1 12:00:00,gnu/usr.bin/texinfo
 2013/12/1 12:00:00,gnu/Makefile