Importing games/adventure
No Minix specific changes needed. Change-Id: I6826d660c60a9e01676e21ef9b95d27e64a67aa5
This commit is contained in:
parent
71d1d39e61
commit
0819c9f89b
21 changed files with 6636 additions and 1 deletions
|
@ -556,6 +556,9 @@
|
||||||
./usr/etc/daily minix-sys
|
./usr/etc/daily minix-sys
|
||||||
./usr/etc/dhcptags.conf minix-sys
|
./usr/etc/dhcptags.conf minix-sys
|
||||||
./usr/etc/rc 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 minix-sys
|
||||||
./usr/include/aio.h minix-sys
|
./usr/include/aio.h minix-sys
|
||||||
./usr/include/a.out.h minix-sys
|
./usr/include/a.out.h minix-sys
|
||||||
|
@ -4746,6 +4749,7 @@
|
||||||
./usr/man/man5/usermgmt.conf.5 minix-sys
|
./usr/man/man5/usermgmt.conf.5 minix-sys
|
||||||
./usr/man/man5/utmp.5 minix-sys
|
./usr/man/man5/utmp.5 minix-sys
|
||||||
./usr/man/man6 minix-sys
|
./usr/man/man6 minix-sys
|
||||||
|
./usr/man/man6/adventure.6 minix-sys
|
||||||
./usr/man/man7 minix-sys
|
./usr/man/man7 minix-sys
|
||||||
./usr/man/man7/ascii.7 minix-sys
|
./usr/man/man7/ascii.7 minix-sys
|
||||||
./usr/man/man7/atf.7 minix-sys atf
|
./usr/man/man7/atf.7 minix-sys atf
|
||||||
|
@ -4990,6 +4994,7 @@
|
||||||
./usr/share/examples/lutok/hello.cpp minix-sys kyua
|
./usr/share/examples/lutok/hello.cpp minix-sys kyua
|
||||||
./usr/share/examples/lutok/interpreter.cpp minix-sys kyua
|
./usr/share/examples/lutok/interpreter.cpp minix-sys kyua
|
||||||
./usr/share/examples/lutok/raii.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 minix-sys
|
||||||
./usr/share/info/as.info minix-sys binutils
|
./usr/share/info/as.info minix-sys binutils
|
||||||
./usr/share/info/bfd.info minix-sys binutils
|
./usr/share/info/bfd.info minix-sys binutils
|
||||||
|
|
|
@ -42,6 +42,8 @@
|
||||||
./usr/benchmarks/unixbench/tmp
|
./usr/benchmarks/unixbench/tmp
|
||||||
./usr/benchmarks/unixbench/testdir
|
./usr/benchmarks/unixbench/testdir
|
||||||
./usr/benchmarks/unixbench/results
|
./usr/benchmarks/unixbench/results
|
||||||
|
./usr/games
|
||||||
|
./usr/games/hide gname=games mode=0750
|
||||||
./usr/include
|
./usr/include
|
||||||
./usr/include/arpa
|
./usr/include/arpa
|
||||||
./usr/include/compat
|
./usr/include/compat
|
||||||
|
@ -111,6 +113,7 @@
|
||||||
./usr/share/doc/psd
|
./usr/share/doc/psd
|
||||||
./usr/share/doc/psd/19.curses
|
./usr/share/doc/psd/19.curses
|
||||||
./usr/share/info
|
./usr/share/info
|
||||||
|
./usr/share/games
|
||||||
./usr/share/misc
|
./usr/share/misc
|
||||||
./usr/share/mk
|
./usr/share/mk
|
||||||
./usr/share/nvi
|
./usr/share/nvi
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
set -o emacs
|
set -o emacs
|
||||||
|
|
||||||
# Set the default path
|
# 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
|
# Add ~/bin, iff it is present
|
||||||
if [ -e ${HOME}/bin ]; then
|
if [ -e ${HOME}/bin ]; then
|
||||||
|
|
18
games/Makefile
Normal file
18
games/Makefile
Normal file
|
@ -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>
|
23
games/Makefile.inc
Normal file
23
games/Makefile.inc
Normal file
|
@ -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
|
19
games/adventure/Makefile
Normal file
19
games/adventure/Makefile
Normal file
|
@ -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>
|
55
games/adventure/adventure.6
Normal file
55
games/adventure/adventure.6
Normal file
|
@ -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 .
|
145
games/adventure/crc.c
Normal file
145
games/adventure/crc.c
Normal file
|
@ -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;
|
||||||
|
}
|
172
games/adventure/done.c
Normal file
172
games/adventure/done.c
Normal file
|
@ -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;
|
||||||
|
}
|
112
games/adventure/extern.h
Normal file
112
games/adventure/extern.h
Normal file
|
@ -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);
|
1815
games/adventure/glorkz
Normal file
1815
games/adventure/glorkz
Normal file
File diff suppressed because it is too large
Load diff
157
games/adventure/hdr.h
Normal file
157
games/adventure/hdr.h
Normal file
|
@ -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+'%')
|
302
games/adventure/init.c
Normal file
302
games/adventure/init.c
Normal file
|
@ -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 */
|
||||||
|
}
|
610
games/adventure/io.c
Normal file
610
games/adventure/io.c
Normal file
|
@ -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(<ext[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(<ext[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);
|
||||||
|
}
|
763
games/adventure/main.c
Normal file
763
games/adventure/main.c
Normal file
|
@ -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 = <ext[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;
|
||||||
|
}
|
||||||
|
}
|
868
games/adventure/save.c
Normal file
868
games/adventure/save.c
Normal file
|
@ -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;
|
||||||
|
}
|
128
games/adventure/setup.c
Normal file
128
games/adventure/setup.c
Normal file
|
@ -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);
|
||||||
|
}
|
1057
games/adventure/subr.c
Normal file
1057
games/adventure/subr.c
Normal file
File diff suppressed because it is too large
Load diff
218
games/adventure/vocab.c
Normal file
218
games/adventure/vocab.c
Normal file
|
@ -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');
|
||||||
|
}
|
||||||
|
}
|
162
games/adventure/wizard.c
Normal file
162
games/adventure/wizard.c
Normal file
|
@ -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);
|
||||||
|
}
|
|
@ -68,6 +68,9 @@
|
||||||
2013/12/1 12:00:00,external/mit/Makefile
|
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/public-domain
|
||||||
2013/12/1 12:00:00,external/README
|
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/dist/texinfo
|
||||||
2013/12/1 12:00:00,gnu/usr.bin/texinfo
|
2013/12/1 12:00:00,gnu/usr.bin/texinfo
|
||||||
2013/12/1 12:00:00,gnu/Makefile
|
2013/12/1 12:00:00,gnu/Makefile
|
||||||
|
|
Loading…
Reference in a new issue