Importing games/adventure

No Minix specific changes needed.

Change-Id: I6826d660c60a9e01676e21ef9b95d27e64a67aa5
This commit is contained in:
Thomas Cort 2014-03-15 15:46:01 -04:00 committed by Lionel Sambuc
parent 71d1d39e61
commit 0819c9f89b
21 changed files with 6636 additions and 1 deletions

View file

@ -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

View file

@ -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

View file

@ -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
View 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
View 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
View 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>

View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

157
games/adventure/hdr.h Normal file
View 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
View 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
View 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(&ltext[loq]);
printf("then\n");
for (t = travel[loq]; t != 0; t = t->next) {
printf("verb %d takes you to ", t->tverb);
if (t->tloc <= 300)
speak(&ltext[t->tloc]);
else
if (t->tloc <= 500)
printf("special code %d\n", t->tloc - 300);
else
rspeak(t->tloc - 500);
printf("under conditions %d\n", t->conditions);
}
}
#endif /* DEBUG */
/* read the vocabulary */
static void
rvoc(void)
{
char *s;
int idx;
char buf[6];
for (;;) {
idx = rnum();
if (idx < 0)
break;
for (s = buf, *s = 0;; s++) /* get the word */
if ((*s = next()) == TAB || *s == '\n' || *s == LF
|| *s == ' ')
break;
/* terminate word with newline, LF, tab, blank */
if (*s != '\n' && *s != LF)
FLUSHLF;/* can be comments */
*s = 0;
/* printf("\"%s\"=%d\n",buf,idx); */
vocab(buf, -2, idx);
}
/* prht(); */
}
/* initial object locations */
static void
rlocs(void)
{
for (;;) {
if ((obj = rnum()) < 0)
break;
plac[obj] = rnum(); /* initial loc for this obj */
if (breakch == TAB) /* there's another entry */
fixd[obj] = rnum();
else
fixd[obj] = 0;
}
}
/* default verb messages */
static void
rdefault(void)
{
for (;;) {
if ((verb = rnum()) < 0)
break;
actspeak[verb] = rnum();
}
}
/* liquid assets &c: cond bits */
static void
rliq(void)
{
int bitnum;
for (;;) { /* read new bit list */
if ((bitnum = rnum()) < 0)
break;
for (;;) { /* read locs for bits */
int n = rnum();
if (n < 0)
break;
cond[n] |= setbit[bitnum];
if (breakch == LF)
break;
}
}
}
static void
rhints(void)
{
int hintnum, i;
hintmax = 0;
for (;;) {
if ((hintnum = rnum()) < 0)
break;
for (i = 1; i < 5; i++)
hints[hintnum][i] = rnum();
if (hintnum > hintmax)
hintmax = hintnum;
}
}
void
rspeak(int msg)
{
if (msg != 0)
speak(&rtext[msg]);
}
void
mspeak(int msg)
{
if (msg != 0)
speak(&mtext[msg]);
}
/* read, decrypt, and print a message (not ptext) */
/* msg is a pointer to seek address and length of mess */
void
speak(const struct text *msg)
{
char *s, nonfirst;
s = msg->seekadr;
nonfirst = 0;
while (s - msg->seekadr < msg->txtlen) { /* read a line at a time */
tape = iotape; /* restart decryption tape */
while ((*s++ ^ *tape++) != TAB); /* read past loc num */
/* assume tape is longer than location number */
/* plus the lookahead put together */
if ((*s ^ *tape) == '>' &&
(*(s + 1) ^ *(tape + 1)) == '$' &&
(*(s + 2) ^ *(tape + 2)) == '<')
break;
if (blklin && !nonfirst++)
putchar('\n');
do {
if (*tape == 0)
tape = iotape; /* rewind decryp tape */
putchar(*s ^ *tape);
} while ((*s++ ^ *tape++) != LF); /* better end with LF */
}
}
/* read, decrypt and print a ptext message */
/* msg is the number of all the p msgs for this place */
/* assumes object 1 doesn't have prop 1, obj 2 no prop 2 &c */
void
pspeak(int m, int skip)
{
char *s, nonfirst;
char *numst;
struct text *msg;
char *tbuf;
msg = &ptext[m];
if ((tbuf = (char *) malloc(msg->txtlen + 1)) == NULL)
err(1, NULL);
memcpy(tbuf, msg->seekadr, msg->txtlen + 1); /* Room to null */
s = tbuf;
nonfirst = 0;
while (s - tbuf < msg->txtlen) { /* read line at a time */
tape = iotape; /* restart decryption tape */
for (numst = s; (*s ^= *tape++) != TAB; s++); /* get number */
/* Temporarily trash the string (cringe) */
*s++ = 0; /* decrypting number within the string */
if (atoi(numst) != 100 * skip && skip >= 0) {
while ((*s++ ^ *tape++) != LF) /* flush the line */
if (*tape == 0)
tape = iotape;
continue;
}
if ((*s ^ *tape) == '>' && (*(s + 1) ^ *(tape + 1)) == '$' &&
(*(s + 2) ^ *(tape + 2)) == '<')
break;
if (blklin && !nonfirst++)
putchar('\n');
do {
if (*tape == 0)
tape = iotape;
putchar(*s ^ *tape);
} while ((*s++ ^ *tape++) != LF); /* better end with LF */
if (skip < 0)
break;
}
free(tbuf);
}

763
games/adventure/main.c Normal file
View 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 = &ltext[loc];
if (!forced(loc) && dark()) {
if (wasdark && pct(35)) {
die(90);
goto l2000;
}
kk = &rtext[16];
}
#if 0
l2001:
#endif
if (toting(bear))
rspeak(141); /* 2001 */
speak(kk);
k = 1;
if (forced(loc))
goto l8;
if (loc == 33 && pct(25) && !isclosing)
rspeak(8);
if (!dark()) {
abb[loc]++;
for (i = atloc[loc]; i != 0; i = links[i]) { /* 2004 */
obj = i;
if (obj > 100)
obj -= 100;
if (obj == steps && toting(nugget))
continue;
if (prop[obj] < 0) {
if (closed)
continue;
prop[obj] = 0;
if (obj == rug || obj == chain)
prop[obj] = 1;
tally--;
if (tally == tally2 && tally != 0)
if (limit > 35)
limit = 35;
}
ll = prop[obj]; /* 2006 */
if (obj == steps && loc == fixed[steps])
ll = 1;
pspeak(obj, ll);
} /* 2008 */
goto l2012;
l2009: k = 54; /* 2009 */
l2010: spk = k;
l2011: rspeak(spk);
}
l2012: verb = 0; /* 2012 */
obj = 0;
l2600: checkhints(); /* to 2600-2602 */
if (closed) {
if (prop[oyster] < 0 && toting(oyster))
pspeak(oyster, 1);
for (i = 1; i < 100; i++)
if (toting(i) && prop[i] < 0) /* 2604 */
prop[i] = -1 - prop[i];
}
wasdark = dark(); /* 2605 */
if (knfloc > 0 && knfloc != loc)
knfloc = 1;
getin(&wd1, &wd2);
if (delhit) { /* user typed a DEL */
delhit = 0; /* reset counter */
copystr("quit", wd1); /* pretend he's quitting */
*wd2 = 0;
}
l2608: if ((foobar = -foobar) > 0)
foobar = 0; /* 2608 */
/* should check here for "magic mode" */
turns++;
if (demo && turns >= SHORT)
done(1); /* to 13000 */
if (verb == say && *wd2 != 0)
verb = 0;
if (verb == say)
goto l4090;
if (tally == 0 && loc >= 15 && loc != 33)
clock1--;
if (clock1 == 0) {
closing(); /* to 10000 */
goto l19999;
}
if (clock1 < 0)
clock2--;
if (clock2 == 0) {
caveclose(); /* to 11000 */
continue; /* back to 2 */
}
if (prop[lamp] == 1)
limit--;
if (limit <= 30 && here(batter) && prop[batter] == 0
&& here(lamp)) {
rspeak(188); /* 12000 */
prop[batter] = 1;
if (toting(batter))
drop(batter, loc);
limit = limit + 2500;
lmwarn = FALSE;
goto l19999;
}
if (limit == 0) {
limit = -1; /* 12400 */
prop[lamp] = 0;
rspeak(184);
goto l19999;
}
if (limit < 0 && loc <= 8) {
rspeak(185); /* 12600 */
gaveup = TRUE;
done(2); /* to 20000 */
}
if (limit <= 30) {
if (lmwarn || !here(lamp))
goto l19999; /* 12200 */
lmwarn = TRUE;
spk = 187;
if (place[batter] == 0)
spk = 183;
if (prop[batter] == 1)
spk = 189;
rspeak(spk);
}
l19999: k = 43;
if (liqloc(loc) == water)
k = 70;
if (weq(wd1, "enter") &&
(weq(wd2, "strea") || weq(wd2, "water")))
goto l2010;
if (weq(wd1, "enter") && *wd2 != 0)
goto l2800;
if ((!weq(wd1, "water") && !weq(wd1, "oil"))
|| (!weq(wd2, "plant") && !weq(wd2, "door")))
goto l2610;
if (at(vocab(wd2, 1, 0)))
copystr("pour", wd2);
l2610: if (weq(wd1, "west"))
if (++iwest == 10)
rspeak(17);
l2630: i = vocab(wd1, -1, 0);
if (i == -1) {
spk = 60; /* 3000 */
if (pct(20))
spk = 61;
if (pct(20))
spk = 13;
rspeak(spk);
goto l2600;
}
k = i % 1000;
kq = i / 1000 + 1;
switch (kq) {
case 1:
goto l8;
case 2:
goto l5000;
case 3:
goto l4000;
case 4:
goto l2010;
default:
bug(22);
}
l8:
switch (march()) {
case 2:
continue; /* i.e. goto l2 */
case 99:
die(99);
goto l2000;
default:
bug(110);
}
l2800: copystr(wd2, wd1);
*wd2 = 0;
goto l2610;
l4000: verb = k;
spk = actspeak[verb];
if (*wd2 != 0 && verb != say)
goto l2800;
if (verb == say)
obj = *wd2;
if (obj != 0)
goto l4090;
#if 0
l4080:
#endif
switch (verb) {
case 1: /* take = 8010 */
if (atloc[loc] == 0 || links[atloc[loc]] != 0)
goto l8000;
for (i = 1; i <= 5; i++)
if (dloc[i] == loc && dflag >= 2)
goto l8000;
obj = atloc[loc];
goto l9010;
case 2:
case 3:
case 9: /* 8000 : drop,say,wave */
case 10:
case 16:
case 17: /* calm,rub,toss */
case 19:
case 21:
case 28: /* find,feed,break */
case 29: /* wake */
l8000: printf("%s what?\n", wd1);
obj = 0;
goto l2600;
case 4:
case 6: /* 8040 open,lock */
spk = 28;
if (here(clam))
obj = clam;
if (here(oyster))
obj = oyster;
if (at(door))
obj = door;
if (at(grate))
obj = grate;
if (obj != 0 && here(chain))
goto l8000;
if (here(chain))
obj = chain;
if (obj == 0)
goto l2011;
goto l9040;
case 5:
goto l2009; /* nothing */
case 7:
goto l9070; /* on */
case 8:
goto l9080; /* off */
case 11:
goto l8000; /* walk */
case 12:
goto l9120; /* kill */
case 13:
goto l9130; /* pour */
case 14: /* eat: 8140 */
if (!here(food))
goto l8000;
l8142: destroy(food);
spk = 72;
goto l2011;
case 15:
goto l9150; /* drink */
case 18: /* quit: 8180 */
gaveup = yes(22, 54, 54);
if (gaveup)
done(2); /* 8185 */
goto l2012;
case 20: /* invent=8200 */
spk = 98;
for (i = 1; i <= 100; i++) {
if (i != bear && toting(i)) {
if (spk == 98)
rspeak(99);
blklin = FALSE;
pspeak(i, -1);
blklin = TRUE;
spk = 0;
}
}
if (toting(bear))
spk = 141;
goto l2011;
case 22:
goto l9220; /* fill */
case 23:
goto l9230; /* blast */
case 24: /* score: 8240 */
scoring = TRUE;
printf("If you were to quit now, you would score");
printf(" %d out of a possible ", score());
printf("%d.", maxscore);
scoring = FALSE;
gaveup = yes(143, 54, 54);
if (gaveup)
done(2);
goto l2012;
case 25: /* foo: 8250 */
k = vocab(wd1, 3, 0);
spk = 42;
if (foobar == 1 - k)
goto l8252;
if (foobar != 0)
spk = 151;
goto l2011;
l8252: foobar = k;
if (k != 4)
goto l2009;
foobar = 0;
if (place[eggs] == plac[eggs]
|| (toting(eggs) && loc == plac[eggs]))
goto l2011;
if (place[eggs] == 0 && place[troll] == 0 &&
prop[troll] == 0)
prop[troll] = 1;
k = 2;
if (here(eggs))
k = 1;
if (loc == plac[eggs])
k = 0;
move(eggs, plac[eggs]);
pspeak(eggs, k);
goto l2012;
case 26: /* brief=8260 */
spk = 156;
abbnum = 10000;
detail = 3;
goto l2011;
case 27: /* read=8270 */
if (here(magazine))
obj = magazine;
if (here(tablet))
obj = obj * 100 + tablet;
if (here(message))
obj = obj * 100 + message;
if (closed && toting(oyster))
obj = oyster;
if (obj > 100 || obj == 0 || dark())
goto l8000;
goto l9270;
case 30: /* suspend=8300 */
spk = 201;
if (demo)
goto l2011;
printf("I can suspend your adventure for you so");
printf(" you can resume later, but\n");
printf("you will have to wait at least");
printf(" %d minutes before continuing.", latency);
if (!yes(200, 54, 54))
goto l2012;
datime(&saveday, &savet);
ciao(); /* Do we quit? */
continue; /* Maybe not */
case 31: /* hours=8310 */
printf("Colossal cave is closed 9am-5pm Mon ");
printf("through Fri except holidays.\n");
goto l2012;
default:
bug(23);
}
l4090:
switch (verb) {
case 1: /* take = 9010 */
l9010: switch (trtake()) {
case 2011:
goto l2011;
case 9220:
goto l9220;
case 2009:
goto l2009;
case 2012:
goto l2012;
default:
bug(102);
}
l9020: case 2: /* drop = 9020 */
switch (trdrop()) {
case 2011:
goto l2011;
case 19000:
done(3);
case 2012:
goto l2012;
default:
bug(105);
}
#if 0
l9030:
#endif
case 3:
switch (trsay()) {
case 2012:
goto l2012;
case 2630:
goto l2630;
default:
bug(107);
}
l9040: case 4:
case 6: /* open, close */
switch (tropen()) {
case 2011:
goto l2011;
case 2010:
goto l2010;
default:
bug(106);
}
case 5:
goto l2009; /* nothing */
case 7: /* on 9070 */
l9070: if (!here(lamp))
goto l2011;
spk = 184;
if (limit < 0)
goto l2011;
prop[lamp] = 1;
rspeak(39);
if (wasdark)
goto l2000;
goto l2012;
case 8: /* off */
l9080: if (!here(lamp))
goto l2011;
prop[lamp] = 0;
rspeak(40);
if (dark())
rspeak(16);
goto l2012;
case 9: /* wave */
if ((!toting(obj)) && (obj != rod || !toting(rod2)))
spk = 29;
if (obj != rod || !at(fissure) || !toting(obj) || isclosing)
goto l2011;
prop[fissure] = 1 - prop[fissure];
pspeak(fissure, 2 - prop[fissure]);
goto l2012;
case 10:
case 11:
case 18: /* calm, walk, quit */
case 24:
case 25:
case 26: /* score, foo, brief */
case 30:
case 31: /* suspend, hours */
goto l2011;
l9120: case 12:/* kill */
switch (trkill()) {
case 8000:
goto l8000;
case 8:
goto l8;
case 2011:
goto l2011;
case 2608:
goto l2608;
case 19000:
done(3);
default:
bug(112);
}
l9130: case 13:/* pour */
if (obj == bottle || obj == 0)
obj = liq();
if (obj == 0)
goto l8000;
if (!toting(obj))
goto l2011;
spk = 78;
if (obj != oil && obj != water)
goto l2011;
prop[bottle] = 1;
place[obj] = 0;
spk = 77;
if (!(at(plant) || at(door)))
goto l2011;
if (at(door)) {
prop[door] = 0; /* 9132 */
if (obj == oil)
prop[door] = 1;
spk = 113 + prop[door];
goto l2011;
}
spk = 112;
if (obj != water)
goto l2011;
pspeak(plant, prop[plant] + 1);
prop[plant] = (prop[plant] + 2) % 6;
prop[plant2] = prop[plant] / 2;
k = null;
goto l8;
case 14: /* 9140 - eat */
if (obj == food)
goto l8142;
if (obj == bird || obj == snake || obj == clam
|| obj == oyster || obj == dwarf || obj == dragon
|| obj == troll || obj == bear)
spk = 71;
goto l2011;
l9150: case 15:/* 9150 - drink */
if (obj == 0 && liqloc(loc) != water && (liq() != water
|| !here(bottle)))
goto l8000;
if (obj != 0 && obj != water)
spk = 110;
if (spk == 110 || liq() != water || !here(bottle))
goto l2011;
prop[bottle] = 1;
place[water] = 0;
spk = 74;
goto l2011;
case 16: /* 9160: rub */
if (obj != lamp)
spk = 76;
goto l2011;
case 17: /* 9170: throw */
switch (trtoss()) {
case 2011:
goto l2011;
case 9020:
goto l9020;
case 9120:
goto l9120;
case 8:
goto l8;
case 9210:
goto l9210;
default:
bug(113);
}
case 19:
case 20: /* 9190: find, invent */
if (at(obj) || (liq() == obj && at(bottle))
|| k == liqloc(loc))
spk = 94;
for (i = 1; i <= 5; i++)
if (dloc[i] == loc && dflag >= 2
&& obj == dwarf)
spk = 94;
if (closed)
spk = 138;
if (toting(obj))
spk = 24;
goto l2011;
l9210: case 21:/* feed */
switch (trfeed()) {
case 2011:
goto l2011;
default:
bug(114);
}
l9220: case 22:/* fill */
switch (trfill()) {
case 2011:
goto l2011;
case 8000:
goto l8000;
case 9020:
goto l9020;
default:
bug(115);
}
l9230: case 23:/* blast */
if (prop[rod2] < 0 || !closed)
goto l2011;
bonus = 133;
if (loc == 115)
bonus = 134;
if (here(rod2))
bonus = 135;
rspeak(bonus);
done(2);
l9270: case 27:/* read */
if (dark())
goto l5190;
if (obj == magazine)
spk = 190;
if (obj == tablet)
spk = 196;
if (obj == message)
spk = 191;
if (obj == oyster && hinted[2] && toting(oyster))
spk = 194;
if (obj != oyster || hinted[2] || !toting(oyster)
|| !closed)
goto l2011;
hinted[2] = yes(192, 193, 54);
goto l2012;
#if 0
l9280:
#endif
case 28: /* break */
if (obj == mirror)
spk = 148;
if (obj == vase && prop[vase] == 0) {
spk = 198;
if (toting(vase))
drop(vase, loc);
prop[vase] = 2;
fixed[vase] = -1;
goto l2011;
}
if (obj != mirror || !closed)
goto l2011;
rspeak(197);
done(3);
#if 0
l9290:
#endif
case 29: /* wake */
if (obj != dwarf || !closed)
goto l2011;
rspeak(199);
done(3);
default:
bug(24);
}
l5000:
obj = k;
if (fixed[k] != loc && !here(k))
goto l5100;
l5010: if (*wd2 != 0)
goto l2800;
if (verb != 0)
goto l4090;
printf("What do you want to do with the %s?\n", wd1);
goto l2600;
l5100: if (k != grate)
goto l5110;
if (loc == 1 || loc == 4 || loc == 7)
k = depression;
if (loc > 9 && loc < 15)
k = entrance;
if (k != grate)
goto l8;
l5110: if (k != dwarf)
goto l5120;
for (i = 1; i <= 5; i++)
if (dloc[i] == loc && dflag >= 2)
goto l5010;
l5120: if ((liq() == k && here(bottle)) || k == liqloc(loc))
goto l5010;
if (obj != plant || !at(plant2) || prop[plant2] == 0)
goto l5130;
obj = plant2;
goto l5010;
l5130: if (obj != knife || knfloc != loc)
goto l5140;
knfloc = -1;
spk = 116;
goto l2011;
l5140: if (obj != rod || !here(rod2))
goto l5190;
obj = rod2;
goto l5010;
l5190: if ((verb == find || verb == invent) && *wd2 == 0)
goto l5010;
printf("I see no %s here\n", wd1);
goto l2012;
}
}

868
games/adventure/save.c Normal file
View 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
View 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

File diff suppressed because it is too large Load diff

218
games/adventure/vocab.c Normal file
View 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
View 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);
}

View file

@ -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