Importing games/adventure
No Minix specific changes needed. Change-Id: I6826d660c60a9e01676e21ef9b95d27e64a67aa5
This commit is contained in:
parent
71d1d39e61
commit
0819c9f89b
21 changed files with 6636 additions and 1 deletions
|
@ -556,6 +556,9 @@
|
|||
./usr/etc/daily minix-sys
|
||||
./usr/etc/dhcptags.conf minix-sys
|
||||
./usr/etc/rc minix-sys
|
||||
./usr/games minix-sys
|
||||
./usr/games/adventure minix-sys
|
||||
./usr/games/hide minix-sys
|
||||
./usr/include minix-sys
|
||||
./usr/include/aio.h minix-sys
|
||||
./usr/include/a.out.h minix-sys
|
||||
|
@ -4746,6 +4749,7 @@
|
|||
./usr/man/man5/usermgmt.conf.5 minix-sys
|
||||
./usr/man/man5/utmp.5 minix-sys
|
||||
./usr/man/man6 minix-sys
|
||||
./usr/man/man6/adventure.6 minix-sys
|
||||
./usr/man/man7 minix-sys
|
||||
./usr/man/man7/ascii.7 minix-sys
|
||||
./usr/man/man7/atf.7 minix-sys atf
|
||||
|
@ -4990,6 +4994,7 @@
|
|||
./usr/share/examples/lutok/hello.cpp minix-sys kyua
|
||||
./usr/share/examples/lutok/interpreter.cpp minix-sys kyua
|
||||
./usr/share/examples/lutok/raii.cpp minix-sys kyua
|
||||
./usr/share/games minix-sys
|
||||
./usr/share/info minix-sys
|
||||
./usr/share/info/as.info minix-sys binutils
|
||||
./usr/share/info/bfd.info minix-sys binutils
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
./usr/benchmarks/unixbench/tmp
|
||||
./usr/benchmarks/unixbench/testdir
|
||||
./usr/benchmarks/unixbench/results
|
||||
./usr/games
|
||||
./usr/games/hide gname=games mode=0750
|
||||
./usr/include
|
||||
./usr/include/arpa
|
||||
./usr/include/compat
|
||||
|
@ -111,6 +113,7 @@
|
|||
./usr/share/doc/psd
|
||||
./usr/share/doc/psd/19.curses
|
||||
./usr/share/info
|
||||
./usr/share/games
|
||||
./usr/share/misc
|
||||
./usr/share/mk
|
||||
./usr/share/nvi
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
set -o emacs
|
||||
|
||||
# Set the default path
|
||||
PATH=/usr/local/bin:/usr/pkg/bin:/usr/bin:/bin
|
||||
PATH=/usr/local/bin:/usr/pkg/bin:/usr/bin:/bin:/usr/games
|
||||
|
||||
# Add ~/bin, iff it is present
|
||||
if [ -e ${HOME}/bin ]; then
|
||||
|
|
18
games/Makefile
Normal file
18
games/Makefile
Normal file
|
@ -0,0 +1,18 @@
|
|||
# $NetBSD: Makefile,v 1.29 2013/11/12 17:46:20 mbalmer Exp $
|
||||
# @(#)Makefile 8.3 (Berkeley) 7/24/94
|
||||
|
||||
# Missing: dungeon warp
|
||||
# Moved: chess
|
||||
# Don't belong: xneko xroach
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
SUBDIR= adventure
|
||||
|
||||
.if !defined(__MINIX)
|
||||
.if ${MKCXX} != "no"
|
||||
SUBDIR+= dab
|
||||
.endif
|
||||
.endif # !defined(__MINIX)
|
||||
|
||||
.include <bsd.subdir.mk>
|
23
games/Makefile.inc
Normal file
23
games/Makefile.inc
Normal file
|
@ -0,0 +1,23 @@
|
|||
# $NetBSD: Makefile.inc,v 1.15 2012/06/19 05:46:08 dholland Exp $
|
||||
# @(#)Makefile.inc 8.1 (Berkeley) 5/31/93
|
||||
|
||||
MKHIDEGAME?= no
|
||||
|
||||
.if defined(HIDEGAME) && (${MKHIDEGAME} != no) && defined(PROG)
|
||||
BINDIR= /usr/games/hide
|
||||
BINGRP= games
|
||||
.if defined(SETGIDGAME)
|
||||
USE_FORT?= yes
|
||||
BINMODE= 2550
|
||||
.else
|
||||
BINMODE= 550
|
||||
.endif
|
||||
SYMLINKS+= dm /usr/games/${PROG}
|
||||
.else
|
||||
BINDIR= /usr/games
|
||||
.if defined(SETGIDGAME)
|
||||
BINGRP= games
|
||||
BINMODE= 2555
|
||||
.endif
|
||||
.endif
|
||||
WARNS?= 5
|
19
games/adventure/Makefile
Normal file
19
games/adventure/Makefile
Normal file
|
@ -0,0 +1,19 @@
|
|||
# $NetBSD: Makefile,v 1.14 2013/02/16 16:30:28 jmcneill Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/12/93
|
||||
|
||||
PROG= adventure
|
||||
SRCS= main.c init.c done.c save.c subr.c vocab.c wizard.c io.c data.c crc.c
|
||||
MAN= adventure.6
|
||||
HIDEGAME=hidegame
|
||||
CLEANFILES+=mkdata setup.lo data.c
|
||||
|
||||
data.c: glorkz mkdata
|
||||
${_MKTARGET_CREATE}
|
||||
./mkdata ${.CURDIR}/glorkz > data.c
|
||||
|
||||
setup.lo: hdr.h
|
||||
mkdata: setup.lo
|
||||
${_MKTARGET_LINK}
|
||||
${HOST_LINK.c} -o ${.TARGET} ${.ALLSRC}
|
||||
|
||||
.include <bsd.prog.mk>
|
55
games/adventure/adventure.6
Normal file
55
games/adventure/adventure.6
Normal file
|
@ -0,0 +1,55 @@
|
|||
.\" $NetBSD: adventure.6,v 1.4 2003/08/07 09:36:50 agc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" The game adventure was originally written in Fortran by Will Crowther
|
||||
.\" and Don Woods. It was later translated to C and enhanced by Jim
|
||||
.\" Gillogly. This code is derived from software contributed to Berkeley
|
||||
.\" by Jim Gillogly at The Rand Corporation.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)adventure.6 8.1 (Berkeley) 5/31/93
|
||||
.\"
|
||||
.Dd May 31, 1993
|
||||
.Dt ADVENTURE 6
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm adventure
|
||||
.Nd an exploration game
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op saved-file
|
||||
.Sh DESCRIPTION
|
||||
The object of the game is to locate and explore Colossal Cave, find the
|
||||
treasures hidden there, and bring them back to the building with you.
|
||||
The program is self-descriptive to a point, but part of the game is to
|
||||
discover its rules.
|
||||
.Pp
|
||||
To terminate a game, enter
|
||||
.Dq quit ;
|
||||
to save a game for later resumption, enter
|
||||
.Dq suspend .
|
145
games/adventure/crc.c
Normal file
145
games/adventure/crc.c
Normal file
|
@ -0,0 +1,145 @@
|
|||
/* $NetBSD: crc.c,v 1.13 2012/01/08 18:16:00 dholland Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* James W. Williams of the University of Maryland.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)crc.c 8.1 (Berkeley) 5/31/93";
|
||||
static char ORIGINAL_sccsid[] = "@(#)crc.c 5.2 (Berkeley) 4/4/91";
|
||||
#else
|
||||
__RCSID("$NetBSD: crc.c,v 1.13 2012/01/08 18:16:00 dholland Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
static const uint32_t crctab[256] = {
|
||||
0x7fffffff,
|
||||
0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e,
|
||||
0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
|
||||
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d,
|
||||
0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0,
|
||||
0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63,
|
||||
0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa,
|
||||
0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75,
|
||||
0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180,
|
||||
0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
|
||||
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87,
|
||||
0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
||||
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5,
|
||||
0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
|
||||
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4,
|
||||
0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b,
|
||||
0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea,
|
||||
0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541,
|
||||
0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc,
|
||||
0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f,
|
||||
0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
|
||||
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e,
|
||||
0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c,
|
||||
0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
|
||||
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b,
|
||||
0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2,
|
||||
0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671,
|
||||
0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8,
|
||||
0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767,
|
||||
0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6,
|
||||
0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
|
||||
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795,
|
||||
0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
||||
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b,
|
||||
0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
|
||||
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82,
|
||||
0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d,
|
||||
0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8,
|
||||
0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff,
|
||||
0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee,
|
||||
0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d,
|
||||
0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
|
||||
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c,
|
||||
0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
||||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02,
|
||||
0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
/*
|
||||
* crc --
|
||||
* Compute a POSIX.2 checksum. This routine modified by Jim Gillogly
|
||||
* to work on sequential data rather than on a file. Initial call to
|
||||
* crc_start initializes the sum, and subsequent calls to crc update
|
||||
* it.
|
||||
*/
|
||||
|
||||
void
|
||||
crc_start(struct crcstate *c)
|
||||
{
|
||||
c->crcval = 0;
|
||||
c->step = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process NUM bytes pointed to by DATA
|
||||
*/
|
||||
void
|
||||
crc_add(struct crcstate *c, const void *data, size_t num)
|
||||
{
|
||||
const unsigned char *udata;
|
||||
size_t pos;
|
||||
unsigned x;
|
||||
|
||||
udata = data;
|
||||
pos = 0;
|
||||
while (pos < num) {
|
||||
x = (c->crcval >> 24 ^ udata[pos++]) & 0xff;
|
||||
if (x == 0) {
|
||||
x = c->step++;
|
||||
if (c->step >= __arraycount(crctab)) {
|
||||
c->step = 0;
|
||||
}
|
||||
}
|
||||
c->crcval = (c->crcval << 8) ^ crctab[x];
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
crc_get(struct crcstate *c)
|
||||
{
|
||||
return c->crcval;
|
||||
}
|
172
games/adventure/done.c
Normal file
172
games/adventure/done.c
Normal file
|
@ -0,0 +1,172 @@
|
|||
/* $NetBSD: done.c,v 1.10 2009/08/25 06:56:52 dholland Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* The game adventure was originally written in Fortran by Will Crowther
|
||||
* and Don Woods. It was later translated to C and enhanced by Jim
|
||||
* Gillogly. This code is derived from software contributed to Berkeley
|
||||
* by Jim Gillogly at The Rand Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)done.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: done.c,v 1.10 2009/08/25 06:56:52 dholland Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
/* Re-coding of advent in C: termination routines */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "hdr.h"
|
||||
#include "extern.h"
|
||||
|
||||
int
|
||||
score(void)
|
||||
{ /* sort of like 20000 */
|
||||
int myscore, i;
|
||||
|
||||
maxscore = myscore = 0;
|
||||
for (i = 50; i <= maxtrs; i++) {
|
||||
if (ptext[i].txtlen == 0)
|
||||
continue;
|
||||
k = 12;
|
||||
if (i == chest)
|
||||
k = 14;
|
||||
if (i > chest)
|
||||
k = 16;
|
||||
if (prop[i] >= 0)
|
||||
myscore += 2;
|
||||
if (place[i] == 3 && prop[i] == 0)
|
||||
myscore += k - 2;
|
||||
maxscore += k;
|
||||
}
|
||||
myscore += (maxdie - numdie) * 10;
|
||||
maxscore += maxdie * 10;
|
||||
if (!(scoring || gaveup))
|
||||
myscore += 4;
|
||||
maxscore += 4;
|
||||
if (dflag != 0)
|
||||
myscore += 25;
|
||||
maxscore += 25;
|
||||
if (isclosing)
|
||||
myscore += 25;
|
||||
maxscore += 25;
|
||||
if (closed) {
|
||||
if (bonus == 0)
|
||||
myscore += 10;
|
||||
if (bonus == 135)
|
||||
myscore += 25;
|
||||
if (bonus == 134)
|
||||
myscore += 30;
|
||||
if (bonus == 133)
|
||||
myscore += 45;
|
||||
}
|
||||
maxscore += 45;
|
||||
if (place[magazine] == 108)
|
||||
myscore++;
|
||||
maxscore++;
|
||||
myscore += 2;
|
||||
maxscore += 2;
|
||||
for (i = 1; i <= hintmax; i++)
|
||||
if (hinted[i])
|
||||
myscore -= hints[i][2];
|
||||
return myscore;
|
||||
}
|
||||
|
||||
/* entry=1 means goto 13000 */ /* game is over */
|
||||
/* entry=2 means goto 20000 */ /* 3=19000 */
|
||||
void
|
||||
done(int entry)
|
||||
{
|
||||
int i, sc;
|
||||
if (entry == 1)
|
||||
mspeak(1);
|
||||
if (entry == 3)
|
||||
rspeak(136);
|
||||
printf("\n\n\nYou scored %d out of a ", (sc = score()));
|
||||
printf("possible %d using %d turns.\n", maxscore, turns);
|
||||
for (i = 1; i <= classes; i++)
|
||||
if (cval[i] >= sc) {
|
||||
speak(&ctext[i]);
|
||||
if (i == classes - 1) {
|
||||
printf("To achieve the next higher rating");
|
||||
printf(" would be a neat trick!\n\n");
|
||||
printf("Congratulations!!\n");
|
||||
exit(0);
|
||||
}
|
||||
k = cval[i] + 1 - sc;
|
||||
printf("To achieve the next higher rating, you need");
|
||||
printf(" %d more point", k);
|
||||
if (k == 1)
|
||||
printf(".\n");
|
||||
else
|
||||
printf("s.\n");
|
||||
exit(0);
|
||||
}
|
||||
printf("You just went off my scale!!!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* label 90 */
|
||||
void
|
||||
die(int entry)
|
||||
{
|
||||
int i;
|
||||
if (entry != 99) {
|
||||
rspeak(23);
|
||||
oldloc2 = loc;
|
||||
}
|
||||
if (isclosing) { /* 99 */
|
||||
rspeak(131);
|
||||
numdie++;
|
||||
done(2);
|
||||
}
|
||||
yea = yes(81 + numdie * 2, 82 + numdie * 2, 54);
|
||||
numdie++;
|
||||
if (numdie == maxdie || !yea)
|
||||
done(2);
|
||||
place[water] = 0;
|
||||
place[oil] = 0;
|
||||
if (toting(lamp))
|
||||
prop[lamp] = 0;
|
||||
for (i = 100; i >= 1; i--) {
|
||||
if (!toting(i))
|
||||
continue;
|
||||
k = oldloc2;
|
||||
if (i == lamp)
|
||||
k = 1;
|
||||
drop(i, k);
|
||||
}
|
||||
loc = 3;
|
||||
oldloc = loc;
|
||||
}
|
112
games/adventure/extern.h
Normal file
112
games/adventure/extern.h
Normal file
|
@ -0,0 +1,112 @@
|
|||
/* $NetBSD: extern.h,v 1.16 2012/01/08 18:17:41 dholland Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 Christos Zoulas. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* crc.c */
|
||||
struct crcstate {
|
||||
uint32_t crcval;
|
||||
unsigned step;
|
||||
};
|
||||
|
||||
void crc_start(struct crcstate *);
|
||||
void crc_add(struct crcstate *, const void *, size_t);
|
||||
uint32_t crc_get(struct crcstate *);
|
||||
|
||||
/* done.c */
|
||||
int score(void);
|
||||
void done(int) __dead;
|
||||
void die(int);
|
||||
|
||||
/* init.c */
|
||||
void init(void);
|
||||
char *decr(int, int, int, int, int);
|
||||
void trapdel(int);
|
||||
void startup(void);
|
||||
|
||||
/* io.c */
|
||||
void getin(char **, char **);
|
||||
int yes(int, int, int);
|
||||
int yesm(int, int, int);
|
||||
void rdata(void);
|
||||
#ifdef DEBUG
|
||||
void twrite(int);
|
||||
#endif
|
||||
void rspeak(int);
|
||||
void mspeak(int);
|
||||
struct text;
|
||||
void speak(const struct text *);
|
||||
void pspeak(int, int);
|
||||
|
||||
/* save.c */
|
||||
int save(const char *);
|
||||
int restore(const char *);
|
||||
|
||||
/* subr.c */
|
||||
int toting(int);
|
||||
int here(int);
|
||||
int at(int);
|
||||
int liq(void);
|
||||
int liqloc(int);
|
||||
int forced(int);
|
||||
int dark(void);
|
||||
int pct(int);
|
||||
int fdwarf(void);
|
||||
int march(void);
|
||||
void bug(int) __dead;
|
||||
void checkhints(void);
|
||||
int trsay(void);
|
||||
int trtake(void);
|
||||
int trdrop(void);
|
||||
int tropen(void);
|
||||
int trkill(void);
|
||||
int trtoss(void);
|
||||
int trfeed(void);
|
||||
int trfill(void);
|
||||
void closing(void);
|
||||
void caveclose(void);
|
||||
|
||||
/* vocab.c */
|
||||
void destroy(int);
|
||||
void juggle(int);
|
||||
void move(int, int);
|
||||
int put(int, int, int);
|
||||
void carry(int, int);
|
||||
void drop(int, int);
|
||||
int vocab(const char *, int, int);
|
||||
|
||||
/* These three used to be functions in vocab.c */
|
||||
#define copystr(src, dest) strcpy((dest), (src))
|
||||
#define weq(str1, str2) (!strncmp((str1), (str2), 5))
|
||||
#define length(str) (strlen((str)) + 1)
|
||||
|
||||
/* wizard.c */
|
||||
void datime(int *, int *);
|
||||
void poof(void);
|
||||
int Start(void);
|
||||
void ciao(void);
|
||||
int ran(int);
|
1815
games/adventure/glorkz
Normal file
1815
games/adventure/glorkz
Normal file
File diff suppressed because it is too large
Load diff
157
games/adventure/hdr.h
Normal file
157
games/adventure/hdr.h
Normal file
|
@ -0,0 +1,157 @@
|
|||
/* $NetBSD: hdr.h,v 1.13 2009/08/25 06:56:52 dholland Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* The game adventure was originally written in Fortran by Will Crowther
|
||||
* and Don Woods. It was later translated to C and enhanced by Jim
|
||||
* Gillogly. This code is derived from software contributed to Berkeley
|
||||
* by Jim Gillogly at The Rand Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)hdr.h 8.1 (Berkeley) 5/31/93
|
||||
*/
|
||||
|
||||
/* ADVENTURE -- Jim Gillogly, Jul 1977
|
||||
* This program is a re-write of ADVENT, written in FORTRAN mostly by
|
||||
* Don Woods of SAIL. In most places it is as nearly identical to the
|
||||
* original as possible given the language and word-size differences.
|
||||
* A few places, such as the message arrays and travel arrays were changed
|
||||
* to reflect the smaller core size and word size. The labels of the
|
||||
* original are reflected in this version, so that the comments of the
|
||||
* fortran are still applicable here.
|
||||
*
|
||||
* The data file distributed with the fortran source is assumed to be called
|
||||
* "glorkz" in the directory where the program is first run.
|
||||
*
|
||||
* The original FORTRAN version can be found at
|
||||
* <URL:ftp://ftp.gmd.de/if-archive/games/source/advent-original.tar.gz>.
|
||||
*/
|
||||
|
||||
/* hdr.h: included by c advent files */
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
extern volatile sig_atomic_t delhit;
|
||||
extern int yea;
|
||||
extern char data_file[]; /* Virtual data file */
|
||||
|
||||
#define TAB 011
|
||||
#define LF 012
|
||||
#define FLUSHLINE do { int flushline_ch; while ((flushline_ch = getchar()) != EOF && flushline_ch != '\n'); } while (0)
|
||||
#define FLUSHLF while (next()!=LF)
|
||||
|
||||
extern int loc, newloc, oldloc, oldloc2, wasdark, gaveup, kq, k, k2;
|
||||
extern char *wd1, *wd2; /* the complete words */
|
||||
extern int verb, obj, spk;
|
||||
extern int blklin;
|
||||
extern int saveday, savet, maxscore, latency;
|
||||
|
||||
#define SHORT 50 /* How short is a demo game? */
|
||||
|
||||
#define MAXSTR 20 /* max length of user's words */
|
||||
|
||||
#define HTSIZE 512 /* max number of vocab words */
|
||||
extern struct hashtab { /* hash table for vocabulary */
|
||||
int val; /* word type &index (ktab) */
|
||||
char *atab; /* pointer to actual string */
|
||||
} voc[HTSIZE];
|
||||
#define SEED 1815622 /* "Encryption" seed */
|
||||
|
||||
struct text {
|
||||
char *seekadr;/* Msg start in virtual disk */
|
||||
int txtlen; /* length of msg starting here */
|
||||
};
|
||||
|
||||
#define RTXSIZE 205
|
||||
extern struct text rtext[RTXSIZE]; /* random text messages */
|
||||
|
||||
#define MAGSIZE 35
|
||||
extern struct text mtext[MAGSIZE]; /* magic messages */
|
||||
|
||||
extern int classes;
|
||||
#define CLSMAX 12
|
||||
extern struct text ctext[CLSMAX]; /* classes of adventurer */
|
||||
extern int cval[CLSMAX];
|
||||
|
||||
extern struct text ptext[101]; /* object descriptions */
|
||||
|
||||
#define LOCSIZE 141 /* number of locations */
|
||||
extern struct text ltext[LOCSIZE]; /* long loc description */
|
||||
extern struct text stext[LOCSIZE]; /* short loc descriptions */
|
||||
|
||||
extern struct travlist { /* direcs & conditions of travel */
|
||||
struct travlist *next; /* ptr to next list entry */
|
||||
int conditions; /* m in writeup (newloc / 1000) */
|
||||
int tloc; /* n in writeup (newloc % 1000) */
|
||||
int tverb; /* the verb that takes you there */
|
||||
} *travel[LOCSIZE], *tkk; /* travel is closer to keys(...) */
|
||||
|
||||
extern int atloc[LOCSIZE];
|
||||
|
||||
extern int plac[101]; /* initial object placement */
|
||||
extern int fixd[101], fixed[101]; /* location fixed? */
|
||||
|
||||
extern int actspeak[35]; /* rtext msg for verb <n> */
|
||||
|
||||
extern int cond[LOCSIZE]; /* various condition bits */
|
||||
|
||||
extern int setbit[16]; /* bit defn masks 1,2,4,... */
|
||||
|
||||
extern int hintmax;
|
||||
extern int hints[20][5]; /* info on hints */
|
||||
extern int hinted[20], hintlc[20];
|
||||
|
||||
extern int place[101], prop[101], links[201];
|
||||
extern int abb[LOCSIZE];
|
||||
|
||||
extern int maxtrs, tally, tally2; /* treasure values */
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
extern int keys, lamp, grate, cage, rod, rod2, steps, /* mnemonics */
|
||||
bird, door, pillow, snake, fissure, tablet, clam, oyster,
|
||||
magazine, dwarf, knife, food, bottle, water, oil, plant, plant2,
|
||||
axe, mirror, dragon, chasm, troll, troll2, bear, message,
|
||||
vend, batter, nugget, coins, chest, eggs, trident, vase,
|
||||
emerald, pyramid, pearl, rug, chain, spices, back, look, cave,
|
||||
null, entrance, depression, /*enter, stream, pour,*/ say, lock,
|
||||
throw, find, invent;
|
||||
|
||||
extern int chloc, chloc2, dseen[7], dloc[7], /* dwarf stuff */
|
||||
odloc[7], dflag, daltloc;
|
||||
|
||||
extern int tk[21], stick, dtotal, attack;
|
||||
extern int turns, lmwarn, iwest, knfloc, detail, /* various flags and
|
||||
* counters */
|
||||
abbnum, maxdie, numdie, holding, dkill, foobar, bonus, clock1,
|
||||
clock2, saved, isclosing, panic, closed, scoring;
|
||||
|
||||
extern int demo, limit;
|
||||
|
||||
#define DECR(a,b,c,d,e) decr(a+'+',b+'-',c+'#',d+'&',e+'%')
|
302
games/adventure/init.c
Normal file
302
games/adventure/init.c
Normal file
|
@ -0,0 +1,302 @@
|
|||
/* $NetBSD: init.c,v 1.20 2011/08/31 16:24:55 plunky Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* The game adventure was originally written in Fortran by Will Crowther
|
||||
* and Don Woods. It was later translated to C and enhanced by Jim
|
||||
* Gillogly. This code is derived from software contributed to Berkeley
|
||||
* by Jim Gillogly at The Rand Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)init.c 8.1 (Berkeley) 6/2/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: init.c,v 1.20 2011/08/31 16:24:55 plunky Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
/* Re-coding of advent in C: data initialization */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "hdr.h"
|
||||
#include "extern.h"
|
||||
|
||||
static void linkdata(void);
|
||||
|
||||
int blklin = TRUE;
|
||||
|
||||
int setbit[16] = {1, 2, 4, 010, 020, 040, 0100, 0200, 0400, 01000, 02000,
|
||||
04000, 010000, 020000, 040000, 0100000};
|
||||
|
||||
volatile sig_atomic_t delhit;
|
||||
int yea;
|
||||
|
||||
int loc, newloc, oldloc, oldloc2, wasdark, gaveup, kq, k, k2;
|
||||
char *wd1, *wd2; /* the complete words */
|
||||
int verb, obj, spk;
|
||||
int saveday, savet, maxscore, latency;
|
||||
|
||||
struct hashtab voc[HTSIZE];
|
||||
|
||||
struct text rtext[RTXSIZE]; /* random text messages */
|
||||
|
||||
struct text mtext[MAGSIZE]; /* magic messages */
|
||||
|
||||
int classes;
|
||||
|
||||
struct text ctext[CLSMAX]; /* classes of adventurer */
|
||||
int cval[CLSMAX];
|
||||
|
||||
struct text ptext[101]; /* object descriptions */
|
||||
|
||||
struct text ltext[LOCSIZE]; /* long loc description */
|
||||
struct text stext[LOCSIZE]; /* short loc descriptions */
|
||||
|
||||
struct travlist *travel[LOCSIZE], *tkk; /* travel is closer to keys(...) */
|
||||
|
||||
int atloc[LOCSIZE];
|
||||
|
||||
int plac[101]; /* initial object placement */
|
||||
int fixd[101], fixed[101]; /* location fixed? */
|
||||
|
||||
int actspeak[35]; /* rtext msg for verb <n> */
|
||||
|
||||
int cond[LOCSIZE]; /* various condition bits */
|
||||
|
||||
int hintmax;
|
||||
int hints[20][5]; /* info on hints */
|
||||
int hinted[20], hintlc[20];
|
||||
|
||||
int place[101], prop[101], links[201];
|
||||
int abb[LOCSIZE];
|
||||
|
||||
int maxtrs, tally, tally2; /* treasure values */
|
||||
|
||||
int keys, lamp, grate, cage, rod, rod2, steps, /* mnemonics */
|
||||
bird, door, pillow, snake, fissure, tablet, clam, oyster,
|
||||
magazine, dwarf, knife, food, bottle, water, oil, plant, plant2,
|
||||
axe, mirror, dragon, chasm, troll, troll2, bear, message,
|
||||
vend, batter, nugget, coins, chest, eggs, trident, vase,
|
||||
emerald, pyramid, pearl, rug, chain, spices, back, look, cave,
|
||||
null, entrance, depression, say, lock, throw,
|
||||
find, invent;
|
||||
|
||||
static int enter, /*stream,*/ pour;
|
||||
|
||||
int chloc, chloc2, dseen[7], dloc[7], /* dwarf stuff */
|
||||
odloc[7], dflag, daltloc;
|
||||
|
||||
int tk[21], stick, dtotal, attack;
|
||||
int turns, lmwarn, iwest, knfloc, detail, /* various flags and
|
||||
* counters */
|
||||
abbnum, maxdie, numdie, holding, dkill, foobar, bonus, clock1,
|
||||
clock2, saved, isclosing, panic, closed, scoring;
|
||||
|
||||
int demo, limit;
|
||||
|
||||
/* everything for 1st time run */
|
||||
void
|
||||
init(void)
|
||||
{
|
||||
rdata(); /* read data from orig. file */
|
||||
linkdata();
|
||||
poof();
|
||||
}
|
||||
|
||||
char *
|
||||
decr(int a, int b, int c, int d, int e)
|
||||
{
|
||||
static char buf[6];
|
||||
|
||||
buf[0] = a - '+';
|
||||
buf[1] = b - '-';
|
||||
buf[2] = c - '#';
|
||||
buf[3] = d - '&';
|
||||
buf[4] = e - '%';
|
||||
buf[5] = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void
|
||||
linkdata(void)
|
||||
{ /* secondary data manipulation */
|
||||
int i, j;
|
||||
|
||||
/* array linkages */
|
||||
for (i = 1; i < LOCSIZE; i++)
|
||||
if (ltext[i].seekadr != 0 && travel[i] != 0)
|
||||
if ((travel[i]->tverb) == 1)
|
||||
cond[i] = 2;
|
||||
for (j = 100; j > 0; j--)
|
||||
if (fixd[j] > 0) {
|
||||
drop(j + 100, fixd[j]);
|
||||
drop(j, plac[j]);
|
||||
}
|
||||
for (j = 100; j > 0; j--) {
|
||||
fixed[j] = fixd[j];
|
||||
if (plac[j] != 0 && fixd[j] <= 0)
|
||||
drop(j, plac[j]);
|
||||
}
|
||||
|
||||
maxtrs = 79;
|
||||
tally = 0;
|
||||
tally2 = 0;
|
||||
|
||||
for (i = 50; i <= maxtrs; i++) {
|
||||
if (ptext[i].seekadr != 0)
|
||||
prop[i] = -1;
|
||||
tally -= prop[i];
|
||||
}
|
||||
|
||||
/* define mnemonics */
|
||||
keys = vocab(DECR('k', 'e', 'y', 's', '\0'), 1, 0);
|
||||
lamp = vocab(DECR('l', 'a', 'm', 'p', '\0'), 1, 0);
|
||||
grate = vocab(DECR('g', 'r', 'a', 't', 'e'), 1, 0);
|
||||
cage = vocab(DECR('c', 'a', 'g', 'e', '\0'), 1, 0);
|
||||
rod = vocab(DECR('r', 'o', 'd', '\0', '\0'), 1, 0);
|
||||
rod2 = rod + 1;
|
||||
steps = vocab(DECR('s', 't', 'e', 'p', 's'), 1, 0);
|
||||
bird = vocab(DECR('b', 'i', 'r', 'd', '\0'), 1, 0);
|
||||
door = vocab(DECR('d', 'o', 'o', 'r', '\0'), 1, 0);
|
||||
pillow = vocab(DECR('p', 'i', 'l', 'l', 'o'), 1, 0);
|
||||
snake = vocab(DECR('s', 'n', 'a', 'k', 'e'), 1, 0);
|
||||
fissure = vocab(DECR('f', 'i', 's', 's', 'u'), 1, 0);
|
||||
tablet = vocab(DECR('t', 'a', 'b', 'l', 'e'), 1, 0);
|
||||
clam = vocab(DECR('c', 'l', 'a', 'm', '\0'), 1, 0);
|
||||
oyster = vocab(DECR('o', 'y', 's', 't', 'e'), 1, 0);
|
||||
magazine = vocab(DECR('m', 'a', 'g', 'a', 'z'), 1, 0);
|
||||
dwarf = vocab(DECR('d', 'w', 'a', 'r', 'f'), 1, 0);
|
||||
knife = vocab(DECR('k', 'n', 'i', 'f', 'e'), 1, 0);
|
||||
food = vocab(DECR('f', 'o', 'o', 'd', '\0'), 1, 0);
|
||||
bottle = vocab(DECR('b', 'o', 't', 't', 'l'), 1, 0);
|
||||
water = vocab(DECR('w', 'a', 't', 'e', 'r'), 1, 0);
|
||||
oil = vocab(DECR('o', 'i', 'l', '\0', '\0'), 1, 0);
|
||||
plant = vocab(DECR('p', 'l', 'a', 'n', 't'), 1, 0);
|
||||
plant2 = plant + 1;
|
||||
axe = vocab(DECR('a', 'x', 'e', '\0', '\0'), 1, 0);
|
||||
mirror = vocab(DECR('m', 'i', 'r', 'r', 'o'), 1, 0);
|
||||
dragon = vocab(DECR('d', 'r', 'a', 'g', 'o'), 1, 0);
|
||||
chasm = vocab(DECR('c', 'h', 'a', 's', 'm'), 1, 0);
|
||||
troll = vocab(DECR('t', 'r', 'o', 'l', 'l'), 1, 0);
|
||||
troll2 = troll + 1;
|
||||
bear = vocab(DECR('b', 'e', 'a', 'r', '\0'), 1, 0);
|
||||
message = vocab(DECR('m', 'e', 's', 's', 'a'), 1, 0);
|
||||
vend = vocab(DECR('v', 'e', 'n', 'd', 'i'), 1, 0);
|
||||
batter = vocab(DECR('b', 'a', 't', 't', 'e'), 1, 0);
|
||||
|
||||
nugget = vocab(DECR('g', 'o', 'l', 'd', '\0'), 1, 0);
|
||||
coins = vocab(DECR('c', 'o', 'i', 'n', 's'), 1, 0);
|
||||
chest = vocab(DECR('c', 'h', 'e', 's', 't'), 1, 0);
|
||||
eggs = vocab(DECR('e', 'g', 'g', 's', '\0'), 1, 0);
|
||||
trident = vocab(DECR('t', 'r', 'i', 'd', 'e'), 1, 0);
|
||||
vase = vocab(DECR('v', 'a', 's', 'e', '\0'), 1, 0);
|
||||
emerald = vocab(DECR('e', 'm', 'e', 'r', 'a'), 1, 0);
|
||||
pyramid = vocab(DECR('p', 'y', 'r', 'a', 'm'), 1, 0);
|
||||
pearl = vocab(DECR('p', 'e', 'a', 'r', 'l'), 1, 0);
|
||||
rug = vocab(DECR('r', 'u', 'g', '\0', '\0'), 1, 0);
|
||||
chain = vocab(DECR('c', 'h', 'a', 'i', 'n'), 1, 0);
|
||||
|
||||
back = vocab(DECR('b', 'a', 'c', 'k', '\0'), 0, 0);
|
||||
look = vocab(DECR('l', 'o', 'o', 'k', '\0'), 0, 0);
|
||||
cave = vocab(DECR('c', 'a', 'v', 'e', '\0'), 0, 0);
|
||||
null = vocab(DECR('n', 'u', 'l', 'l', '\0'), 0, 0);
|
||||
entrance = vocab(DECR('e', 'n', 't', 'r', 'a'), 0, 0);
|
||||
depression = vocab(DECR('d', 'e', 'p', 'r', 'e'), 0, 0);
|
||||
enter = vocab(DECR('e', 'n', 't', 'e', 'r'), 0, 0);
|
||||
|
||||
pour = vocab(DECR('p', 'o', 'u', 'r', '\0'), 2, 0);
|
||||
say = vocab(DECR('s', 'a', 'y', '\0', '\0'), 2, 0);
|
||||
lock = vocab(DECR('l', 'o', 'c', 'k', '\0'), 2, 0);
|
||||
throw = vocab(DECR('t', 'h', 'r', 'o', 'w'), 2, 0);
|
||||
find = vocab(DECR('f', 'i', 'n', 'd', '\0'), 2, 0);
|
||||
invent = vocab(DECR('i', 'n', 'v', 'e', 'n'), 2, 0);
|
||||
|
||||
/* initialize dwarves */
|
||||
chloc = 114;
|
||||
chloc2 = 140;
|
||||
for (i = 1; i <= 6; i++)
|
||||
dseen[i] = FALSE;
|
||||
dflag = 0;
|
||||
dloc[1] = 19;
|
||||
dloc[2] = 27;
|
||||
dloc[3] = 33;
|
||||
dloc[4] = 44;
|
||||
dloc[5] = 64;
|
||||
dloc[6] = chloc;
|
||||
daltloc = 18;
|
||||
|
||||
/* random flags & ctrs */
|
||||
turns = 0;
|
||||
lmwarn = FALSE;
|
||||
iwest = 0;
|
||||
knfloc = 0;
|
||||
detail = 0;
|
||||
abbnum = 5;
|
||||
for (i = 0; i <= 4; i++)
|
||||
if (rtext[2 * i + 81].seekadr != 0)
|
||||
maxdie = i + 1;
|
||||
numdie = holding = dkill = foobar = bonus = 0;
|
||||
clock1 = 30;
|
||||
clock2 = 50;
|
||||
saved = 0;
|
||||
isclosing = panic = closed = scoring = FALSE;
|
||||
}
|
||||
|
||||
/* come here if he hits a del */
|
||||
void
|
||||
trapdel(int n __unused)
|
||||
{
|
||||
delhit = 1; /* main checks, treats as QUIT */
|
||||
signal(SIGINT, trapdel);/* catch subsequent DELs */
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
startup(void)
|
||||
{
|
||||
demo = Start();
|
||||
srand((int)time(NULL)); /* random seed */
|
||||
#if 0
|
||||
srand(371); /* non-random seed */
|
||||
#endif
|
||||
hinted[3] = yes(65, 1, 0);
|
||||
newloc = 1;
|
||||
delhit = 0;
|
||||
limit = 330;
|
||||
if (hinted[3])
|
||||
limit = 1000; /* better batteries if instrucs */
|
||||
}
|
610
games/adventure/io.c
Normal file
610
games/adventure/io.c
Normal file
|
@ -0,0 +1,610 @@
|
|||
/* $NetBSD: io.c,v 1.22 2009/08/25 06:56:52 dholland Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* The game adventure was originally written in Fortran by Will Crowther
|
||||
* and Don Woods. It was later translated to C and enhanced by Jim
|
||||
* Gillogly. This code is derived from software contributed to Berkeley
|
||||
* by Jim Gillogly at The Rand Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)io.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: io.c,v 1.22 2009/08/25 06:56:52 dholland Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
/* Re-coding of advent in C: file i/o and user i/o */
|
||||
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "hdr.h"
|
||||
#include "extern.h"
|
||||
|
||||
static int next(void);
|
||||
static void rdesc(int);
|
||||
static void rdefault(void);
|
||||
static void rhints(void);
|
||||
static void rliq(void);
|
||||
static void rlocs(void);
|
||||
static int rnum(void);
|
||||
static void rtrav(void);
|
||||
static void rvoc(void);
|
||||
|
||||
/* get command from user */
|
||||
/* no prompt, usually */
|
||||
void
|
||||
getin(char **wrd1, char **wrd2)
|
||||
{
|
||||
char *s;
|
||||
static char wd1buf[MAXSTR], wd2buf[MAXSTR];
|
||||
int first, numch, c;
|
||||
|
||||
*wrd1 = wd1buf; /* return ptr to internal str */
|
||||
*wrd2 = wd2buf;
|
||||
wd2buf[0] = 0; /* in case it isn't set here */
|
||||
for (s = wd1buf, first = 1, numch = 0;;) {
|
||||
c = getchar();
|
||||
if ((*s = (char)c) >= 'A' && *s <= 'Z')
|
||||
*s = *s - ('A' - 'a');
|
||||
/* convert to upper case */
|
||||
switch (c) { /* start reading from user */
|
||||
case '\n':
|
||||
*s = 0;
|
||||
return;
|
||||
case ' ':
|
||||
if (s == wd1buf || s == wd2buf) /* initial blank */
|
||||
continue;
|
||||
*s = 0;
|
||||
if (first) { /* finished 1st wd; start 2nd */
|
||||
first = numch = 0;
|
||||
s = wd2buf;
|
||||
break;
|
||||
} else { /* finished 2nd word */
|
||||
FLUSHLINE;
|
||||
*s = 0;
|
||||
return;
|
||||
}
|
||||
case EOF:
|
||||
printf("user closed input stream, quitting...\n");
|
||||
exit(0);
|
||||
default:
|
||||
if (++numch >= MAXSTR) { /* string too long */
|
||||
printf("Give me a break!!\n");
|
||||
wd1buf[0] = wd2buf[0] = 0;
|
||||
FLUSHLINE;
|
||||
return;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* confirm with rspeak */
|
||||
int
|
||||
yes(int x, int y, int z)
|
||||
{
|
||||
int result = TRUE; /* pacify gcc */
|
||||
int ch;
|
||||
for (;;) {
|
||||
rspeak(x); /* tell him what we want */
|
||||
if ((ch = getchar()) == 'y')
|
||||
result = TRUE;
|
||||
else if (ch == 'n')
|
||||
result = FALSE;
|
||||
else if (ch == EOF) {
|
||||
printf("user closed input stream, quitting...\n");
|
||||
exit(0);
|
||||
}
|
||||
FLUSHLINE;
|
||||
if (ch == 'y' || ch == 'n')
|
||||
break;
|
||||
printf("Please answer the question.\n");
|
||||
}
|
||||
if (result == TRUE)
|
||||
rspeak(y);
|
||||
if (result == FALSE)
|
||||
rspeak(z);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* confirm with mspeak */
|
||||
int
|
||||
yesm(int x, int y, int z)
|
||||
{
|
||||
int result = TRUE; /* pacify gcc */
|
||||
int ch;
|
||||
for (;;) {
|
||||
mspeak(x); /* tell him what we want */
|
||||
if ((ch = getchar()) == 'y')
|
||||
result = TRUE;
|
||||
else if (ch == 'n')
|
||||
result = FALSE;
|
||||
else if (ch == EOF) {
|
||||
printf("user closed input stream, quitting...\n");
|
||||
exit(0);
|
||||
}
|
||||
FLUSHLINE;
|
||||
if (ch == 'y' || ch == 'n')
|
||||
break;
|
||||
printf("Please answer the question.\n");
|
||||
}
|
||||
if (result == TRUE)
|
||||
mspeak(y);
|
||||
if (result == FALSE)
|
||||
mspeak(z);
|
||||
return (result);
|
||||
}
|
||||
/* FILE *inbuf,*outbuf; */
|
||||
|
||||
static char *inptr; /* Pointer into virtual disk */
|
||||
|
||||
static int outsw = 0; /* putting stuff to data file? */
|
||||
|
||||
static const char iotape[] = "Ax3F'\003tt$8h\315qer*h\017nGKrX\207:!l";
|
||||
static const char *tape = iotape; /* pointer to encryption tape */
|
||||
|
||||
/* next virtual char, bump adr */
|
||||
static int
|
||||
next(void)
|
||||
{
|
||||
int ch;
|
||||
|
||||
ch = (*inptr ^ random()) & 0xFF; /* Decrypt input data */
|
||||
if (outsw) { /* putting data in tmp file */
|
||||
if (*tape == 0)
|
||||
tape = iotape; /* rewind encryption tape */
|
||||
*inptr = ch ^ *tape++; /* re-encrypt and replace value */
|
||||
}
|
||||
inptr++;
|
||||
return (ch);
|
||||
}
|
||||
|
||||
static char breakch; /* tell which char ended rnum */
|
||||
|
||||
/* "read" data from virtual file */
|
||||
void
|
||||
rdata(void)
|
||||
{
|
||||
int sect;
|
||||
char ch;
|
||||
|
||||
inptr = data_file; /* Pointer to virtual data file */
|
||||
srandom(SEED); /* which is lightly encrypted. */
|
||||
|
||||
classes = 1;
|
||||
for (;;) { /* read data sections */
|
||||
sect = next() - '0'; /* 1st digit of section number */
|
||||
#ifdef VERBOSE
|
||||
printf("Section %c", sect + '0');
|
||||
#endif
|
||||
if ((ch = next()) != LF) { /* is there a second digit? */
|
||||
FLUSHLF;
|
||||
#ifdef VERBOSE
|
||||
putchar(ch);
|
||||
#endif
|
||||
sect = 10 * sect + ch - '0';
|
||||
}
|
||||
#ifdef VERBOSE
|
||||
putchar('\n');
|
||||
#endif
|
||||
switch (sect) {
|
||||
case 0: /* finished reading database */
|
||||
return;
|
||||
case 1: /* long form descriptions */
|
||||
rdesc(1);
|
||||
break;
|
||||
case 2: /* short form descriptions */
|
||||
rdesc(2);
|
||||
break;
|
||||
case 3: /* travel table */
|
||||
rtrav();
|
||||
break;
|
||||
case 4: /* vocabulary */
|
||||
rvoc();
|
||||
break;
|
||||
case 5: /* object descriptions */
|
||||
rdesc(5);
|
||||
break;
|
||||
case 6: /* arbitrary messages */
|
||||
rdesc(6);
|
||||
break;
|
||||
case 7: /* object locations */
|
||||
rlocs();
|
||||
break;
|
||||
case 8: /* action defaults */
|
||||
rdefault();
|
||||
break;
|
||||
case 9: /* liquid assets */
|
||||
rliq();
|
||||
break;
|
||||
case 10: /* class messages */
|
||||
rdesc(10);
|
||||
break;
|
||||
case 11: /* hints */
|
||||
rhints();
|
||||
break;
|
||||
case 12: /* magic messages */
|
||||
rdesc(12);
|
||||
break;
|
||||
default:
|
||||
printf("Invalid data section number: %d\n", sect);
|
||||
for (;;)
|
||||
putchar(next());
|
||||
}
|
||||
if (breakch != LF) /* routines return after "-1" */
|
||||
FLUSHLF;
|
||||
}
|
||||
}
|
||||
|
||||
static char nbf[12];
|
||||
|
||||
/* read initial location num */
|
||||
static int
|
||||
rnum(void)
|
||||
{
|
||||
char *s;
|
||||
tape = iotape; /* restart encryption tape */
|
||||
for (s = nbf, *s = 0;; s++)
|
||||
if ((*s = next()) == TAB || *s == '\n' || *s == LF)
|
||||
break;
|
||||
breakch = *s; /* save char for rtrav() */
|
||||
*s = 0; /* got the number as ascii */
|
||||
if (nbf[0] == '-')
|
||||
return (-1); /* end of data */
|
||||
return (atoi(nbf)); /* convert it to integer */
|
||||
}
|
||||
|
||||
static char *seekhere;
|
||||
|
||||
/* read description-format msgs */
|
||||
static void
|
||||
rdesc(int sect)
|
||||
{
|
||||
int locc;
|
||||
char *seekstart, *maystart;
|
||||
|
||||
seekhere = inptr; /* Where are we in virtual file? */
|
||||
outsw = 1; /* these msgs go into tmp file */
|
||||
for (oldloc = -1, seekstart = seekhere;;) {
|
||||
maystart = inptr; /* maybe starting new entry */
|
||||
if ((locc = rnum()) != oldloc && oldloc >= 0 /* finished msg */
|
||||
/* unless sect 5 */
|
||||
&& !(sect == 5 && (locc == 0 || locc >= 100))) {
|
||||
switch (sect) { /* now put it into right table */
|
||||
case 1:/* long descriptions */
|
||||
ltext[oldloc].seekadr = seekhere;
|
||||
ltext[oldloc].txtlen = maystart - seekstart;
|
||||
break;
|
||||
case 2:/* short descriptions */
|
||||
stext[oldloc].seekadr = seekhere;
|
||||
stext[oldloc].txtlen = maystart - seekstart;
|
||||
break;
|
||||
case 5:/* object descriptions */
|
||||
ptext[oldloc].seekadr = seekhere;
|
||||
ptext[oldloc].txtlen = maystart - seekstart;
|
||||
break;
|
||||
case 6:/* random messages */
|
||||
if (oldloc >= RTXSIZE)
|
||||
errx(1,"Too many random msgs");
|
||||
rtext[oldloc].seekadr = seekhere;
|
||||
rtext[oldloc].txtlen = maystart - seekstart;
|
||||
break;
|
||||
case 10: /* class messages */
|
||||
ctext[classes].seekadr = seekhere;
|
||||
ctext[classes].txtlen = maystart - seekstart;
|
||||
cval[classes++] = oldloc;
|
||||
break;
|
||||
case 12: /* magic messages */
|
||||
if (oldloc >= MAGSIZE)
|
||||
errx(1,"Too many magic msgs");
|
||||
mtext[oldloc].seekadr = seekhere;
|
||||
mtext[oldloc].txtlen = maystart - seekstart;
|
||||
break;
|
||||
default:
|
||||
errx(1,"rdesc called with bad section");
|
||||
}
|
||||
seekhere += maystart - seekstart;
|
||||
}
|
||||
if (locc < 0) {
|
||||
outsw = 0; /* turn off output */
|
||||
seekhere += 3; /* -1<delimiter> */
|
||||
return;
|
||||
}
|
||||
if (sect != 5 || (locc > 0 && locc < 100)) {
|
||||
if (oldloc != locc) /* starting a new message */
|
||||
seekstart = maystart;
|
||||
oldloc = locc;
|
||||
}
|
||||
FLUSHLF; /* scan the line */
|
||||
}
|
||||
}
|
||||
|
||||
/* read travel table */
|
||||
static void
|
||||
rtrav(void)
|
||||
{
|
||||
int locc;
|
||||
struct travlist *t = NULL;
|
||||
char *s;
|
||||
char buf[12];
|
||||
int len, m, n, entries = 0;
|
||||
|
||||
for (oldloc = -1;;) { /* get another line */
|
||||
/* end of entry */
|
||||
if ((locc = rnum()) != oldloc && oldloc >= 0 && t) {
|
||||
t->next = 0; /* terminate the old entry */
|
||||
/* printf("%d:%d entries\n",oldloc,entries); */
|
||||
/* twrite(oldloc); */
|
||||
}
|
||||
if (locc == -1)
|
||||
return;
|
||||
if (locc != oldloc) { /* getting a new entry */
|
||||
t = travel[locc] = calloc(1, sizeof(*t));
|
||||
if (t == NULL)
|
||||
err(1, NULL);
|
||||
/* printf("New travel list for %d\n",locc); */
|
||||
entries = 0;
|
||||
oldloc = locc;
|
||||
}
|
||||
for (s = buf;; s++) /* get the newloc number /ASCII */
|
||||
if ((*s = next()) == TAB || *s == LF)
|
||||
break;
|
||||
*s = 0;
|
||||
len = length(buf) - 1; /* quad long number handling */
|
||||
/* printf("Newloc: %s (%d chars)\n",buf,len); */
|
||||
if (len < 4) { /* no "m" conditions */
|
||||
m = 0;
|
||||
n = atoi(buf); /* newloc mod 1000 = newloc */
|
||||
} else { /* a long integer */
|
||||
n = atoi(buf + len - 3);
|
||||
buf[len - 3] = 0; /* terminate newloc/1000 */
|
||||
m = atoi(buf);
|
||||
}
|
||||
while (breakch != LF) { /* only do one line at a time */
|
||||
if (t == NULL)
|
||||
abort();
|
||||
if (entries++) {
|
||||
t->next = calloc(1, sizeof(*t));
|
||||
if (t->next == NULL)
|
||||
err(1, NULL);
|
||||
t = t->next;
|
||||
}
|
||||
t->tverb = rnum(); /* get verb from the file */
|
||||
t->tloc = n; /* table entry mod 1000 */
|
||||
t->conditions = m; /* table entry / 1000 */
|
||||
/* printf("entry %d for %d\n",entries,locc); */
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
|
||||
/* travel options from this loc */
|
||||
void
|
||||
twrite(int loq)
|
||||
{
|
||||
struct travlist *t;
|
||||
printf("If");
|
||||
speak(<ext[loq]);
|
||||
printf("then\n");
|
||||
for (t = travel[loq]; t != 0; t = t->next) {
|
||||
printf("verb %d takes you to ", t->tverb);
|
||||
if (t->tloc <= 300)
|
||||
speak(<ext[t->tloc]);
|
||||
else
|
||||
if (t->tloc <= 500)
|
||||
printf("special code %d\n", t->tloc - 300);
|
||||
else
|
||||
rspeak(t->tloc - 500);
|
||||
printf("under conditions %d\n", t->conditions);
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* read the vocabulary */
|
||||
static void
|
||||
rvoc(void)
|
||||
{
|
||||
char *s;
|
||||
int idx;
|
||||
char buf[6];
|
||||
for (;;) {
|
||||
idx = rnum();
|
||||
if (idx < 0)
|
||||
break;
|
||||
for (s = buf, *s = 0;; s++) /* get the word */
|
||||
if ((*s = next()) == TAB || *s == '\n' || *s == LF
|
||||
|| *s == ' ')
|
||||
break;
|
||||
/* terminate word with newline, LF, tab, blank */
|
||||
if (*s != '\n' && *s != LF)
|
||||
FLUSHLF;/* can be comments */
|
||||
*s = 0;
|
||||
/* printf("\"%s\"=%d\n",buf,idx); */
|
||||
vocab(buf, -2, idx);
|
||||
}
|
||||
/* prht(); */
|
||||
}
|
||||
|
||||
/* initial object locations */
|
||||
static void
|
||||
rlocs(void)
|
||||
{
|
||||
for (;;) {
|
||||
if ((obj = rnum()) < 0)
|
||||
break;
|
||||
plac[obj] = rnum(); /* initial loc for this obj */
|
||||
if (breakch == TAB) /* there's another entry */
|
||||
fixd[obj] = rnum();
|
||||
else
|
||||
fixd[obj] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* default verb messages */
|
||||
static void
|
||||
rdefault(void)
|
||||
{
|
||||
for (;;) {
|
||||
if ((verb = rnum()) < 0)
|
||||
break;
|
||||
actspeak[verb] = rnum();
|
||||
}
|
||||
}
|
||||
|
||||
/* liquid assets &c: cond bits */
|
||||
static void
|
||||
rliq(void)
|
||||
{
|
||||
int bitnum;
|
||||
for (;;) { /* read new bit list */
|
||||
if ((bitnum = rnum()) < 0)
|
||||
break;
|
||||
for (;;) { /* read locs for bits */
|
||||
int n = rnum();
|
||||
if (n < 0)
|
||||
break;
|
||||
cond[n] |= setbit[bitnum];
|
||||
if (breakch == LF)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rhints(void)
|
||||
{
|
||||
int hintnum, i;
|
||||
hintmax = 0;
|
||||
for (;;) {
|
||||
if ((hintnum = rnum()) < 0)
|
||||
break;
|
||||
for (i = 1; i < 5; i++)
|
||||
hints[hintnum][i] = rnum();
|
||||
if (hintnum > hintmax)
|
||||
hintmax = hintnum;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rspeak(int msg)
|
||||
{
|
||||
if (msg != 0)
|
||||
speak(&rtext[msg]);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mspeak(int msg)
|
||||
{
|
||||
if (msg != 0)
|
||||
speak(&mtext[msg]);
|
||||
}
|
||||
|
||||
|
||||
/* read, decrypt, and print a message (not ptext) */
|
||||
/* msg is a pointer to seek address and length of mess */
|
||||
void
|
||||
speak(const struct text *msg)
|
||||
{
|
||||
char *s, nonfirst;
|
||||
|
||||
s = msg->seekadr;
|
||||
nonfirst = 0;
|
||||
while (s - msg->seekadr < msg->txtlen) { /* read a line at a time */
|
||||
tape = iotape; /* restart decryption tape */
|
||||
while ((*s++ ^ *tape++) != TAB); /* read past loc num */
|
||||
/* assume tape is longer than location number */
|
||||
/* plus the lookahead put together */
|
||||
if ((*s ^ *tape) == '>' &&
|
||||
(*(s + 1) ^ *(tape + 1)) == '$' &&
|
||||
(*(s + 2) ^ *(tape + 2)) == '<')
|
||||
break;
|
||||
if (blklin && !nonfirst++)
|
||||
putchar('\n');
|
||||
do {
|
||||
if (*tape == 0)
|
||||
tape = iotape; /* rewind decryp tape */
|
||||
putchar(*s ^ *tape);
|
||||
} while ((*s++ ^ *tape++) != LF); /* better end with LF */
|
||||
}
|
||||
}
|
||||
|
||||
/* read, decrypt and print a ptext message */
|
||||
/* msg is the number of all the p msgs for this place */
|
||||
/* assumes object 1 doesn't have prop 1, obj 2 no prop 2 &c */
|
||||
void
|
||||
pspeak(int m, int skip)
|
||||
{
|
||||
char *s, nonfirst;
|
||||
char *numst;
|
||||
struct text *msg;
|
||||
char *tbuf;
|
||||
|
||||
msg = &ptext[m];
|
||||
if ((tbuf = (char *) malloc(msg->txtlen + 1)) == NULL)
|
||||
err(1, NULL);
|
||||
memcpy(tbuf, msg->seekadr, msg->txtlen + 1); /* Room to null */
|
||||
s = tbuf;
|
||||
|
||||
nonfirst = 0;
|
||||
while (s - tbuf < msg->txtlen) { /* read line at a time */
|
||||
tape = iotape; /* restart decryption tape */
|
||||
for (numst = s; (*s ^= *tape++) != TAB; s++); /* get number */
|
||||
|
||||
/* Temporarily trash the string (cringe) */
|
||||
*s++ = 0; /* decrypting number within the string */
|
||||
|
||||
if (atoi(numst) != 100 * skip && skip >= 0) {
|
||||
while ((*s++ ^ *tape++) != LF) /* flush the line */
|
||||
if (*tape == 0)
|
||||
tape = iotape;
|
||||
continue;
|
||||
}
|
||||
if ((*s ^ *tape) == '>' && (*(s + 1) ^ *(tape + 1)) == '$' &&
|
||||
(*(s + 2) ^ *(tape + 2)) == '<')
|
||||
break;
|
||||
if (blklin && !nonfirst++)
|
||||
putchar('\n');
|
||||
do {
|
||||
if (*tape == 0)
|
||||
tape = iotape;
|
||||
putchar(*s ^ *tape);
|
||||
} while ((*s++ ^ *tape++) != LF); /* better end with LF */
|
||||
if (skip < 0)
|
||||
break;
|
||||
}
|
||||
free(tbuf);
|
||||
}
|
763
games/adventure/main.c
Normal file
763
games/adventure/main.c
Normal file
|
@ -0,0 +1,763 @@
|
|||
/* $NetBSD: main.c,v 1.21 2009/08/25 06:56:52 dholland Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* The game adventure was originally written in Fortran by Will Crowther
|
||||
* and Don Woods. It was later translated to C and enhanced by Jim
|
||||
* Gillogly. This code is derived from software contributed to Berkeley
|
||||
* by Jim Gillogly at The Rand Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1991, 1993\
|
||||
The Regents of the University of California. All rights reserved.");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/2/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: main.c,v 1.21 2009/08/25 06:56:52 dholland Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
/* Re-coding of advent in C: main program */
|
||||
|
||||
#include <sys/file.h>
|
||||
#include <err.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "hdr.h"
|
||||
#include "extern.h"
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
int rval, ll;
|
||||
struct text *kk;
|
||||
|
||||
/* revoke setgid privileges from dm */
|
||||
setgid(getgid());
|
||||
|
||||
init(); /* Initialize everything */
|
||||
signal(SIGINT, trapdel);
|
||||
|
||||
if (argc > 1) { /* Restore file specified */
|
||||
/* Restart is label 8305 (Fortran) */
|
||||
i = restore(argv[1]); /* See what we've got */
|
||||
switch (i) {
|
||||
case 0: /* The restore worked fine */
|
||||
yea = Start();
|
||||
k = null;
|
||||
unlink(argv[1]); /* Don't re-use the save */
|
||||
goto l8; /* Get where we're going */
|
||||
case 1: /* Couldn't open it */
|
||||
errx(1,"can't open file"); /* So give up */
|
||||
case 2: /* Oops -- file was altered */
|
||||
rspeak(202); /* You dissolve */
|
||||
exit(1); /* File could be non-adventure */
|
||||
} /* So don't unlink it. */
|
||||
}
|
||||
startup(); /* prepare for a user */
|
||||
|
||||
for (;;) { /* main command loop (label 2) */
|
||||
if (newloc < 9 && newloc != 0 && isclosing) {
|
||||
rspeak(130); /* if closing leave only by */
|
||||
newloc = loc; /* main office */
|
||||
if (!panic)
|
||||
clock2 = 15;
|
||||
panic = TRUE;
|
||||
}
|
||||
rval = fdwarf(); /* dwarf stuff */
|
||||
if (rval == 99)
|
||||
die(99);
|
||||
|
||||
l2000: if (loc == 0)
|
||||
die(99); /* label 2000 */
|
||||
kk = &stext[loc];
|
||||
if ((abb[loc] % abbnum) == 0 || kk->seekadr == 0)
|
||||
kk = <ext[loc];
|
||||
if (!forced(loc) && dark()) {
|
||||
if (wasdark && pct(35)) {
|
||||
die(90);
|
||||
goto l2000;
|
||||
}
|
||||
kk = &rtext[16];
|
||||
}
|
||||
#if 0
|
||||
l2001:
|
||||
#endif
|
||||
if (toting(bear))
|
||||
rspeak(141); /* 2001 */
|
||||
speak(kk);
|
||||
k = 1;
|
||||
if (forced(loc))
|
||||
goto l8;
|
||||
if (loc == 33 && pct(25) && !isclosing)
|
||||
rspeak(8);
|
||||
if (!dark()) {
|
||||
abb[loc]++;
|
||||
for (i = atloc[loc]; i != 0; i = links[i]) { /* 2004 */
|
||||
obj = i;
|
||||
if (obj > 100)
|
||||
obj -= 100;
|
||||
if (obj == steps && toting(nugget))
|
||||
continue;
|
||||
if (prop[obj] < 0) {
|
||||
if (closed)
|
||||
continue;
|
||||
prop[obj] = 0;
|
||||
if (obj == rug || obj == chain)
|
||||
prop[obj] = 1;
|
||||
tally--;
|
||||
if (tally == tally2 && tally != 0)
|
||||
if (limit > 35)
|
||||
limit = 35;
|
||||
}
|
||||
ll = prop[obj]; /* 2006 */
|
||||
if (obj == steps && loc == fixed[steps])
|
||||
ll = 1;
|
||||
pspeak(obj, ll);
|
||||
} /* 2008 */
|
||||
goto l2012;
|
||||
l2009: k = 54; /* 2009 */
|
||||
l2010: spk = k;
|
||||
l2011: rspeak(spk);
|
||||
}
|
||||
l2012: verb = 0; /* 2012 */
|
||||
obj = 0;
|
||||
l2600: checkhints(); /* to 2600-2602 */
|
||||
if (closed) {
|
||||
if (prop[oyster] < 0 && toting(oyster))
|
||||
pspeak(oyster, 1);
|
||||
for (i = 1; i < 100; i++)
|
||||
if (toting(i) && prop[i] < 0) /* 2604 */
|
||||
prop[i] = -1 - prop[i];
|
||||
}
|
||||
wasdark = dark(); /* 2605 */
|
||||
if (knfloc > 0 && knfloc != loc)
|
||||
knfloc = 1;
|
||||
getin(&wd1, &wd2);
|
||||
if (delhit) { /* user typed a DEL */
|
||||
delhit = 0; /* reset counter */
|
||||
copystr("quit", wd1); /* pretend he's quitting */
|
||||
*wd2 = 0;
|
||||
}
|
||||
l2608: if ((foobar = -foobar) > 0)
|
||||
foobar = 0; /* 2608 */
|
||||
/* should check here for "magic mode" */
|
||||
turns++;
|
||||
if (demo && turns >= SHORT)
|
||||
done(1); /* to 13000 */
|
||||
|
||||
if (verb == say && *wd2 != 0)
|
||||
verb = 0;
|
||||
if (verb == say)
|
||||
goto l4090;
|
||||
if (tally == 0 && loc >= 15 && loc != 33)
|
||||
clock1--;
|
||||
if (clock1 == 0) {
|
||||
closing(); /* to 10000 */
|
||||
goto l19999;
|
||||
}
|
||||
if (clock1 < 0)
|
||||
clock2--;
|
||||
if (clock2 == 0) {
|
||||
caveclose(); /* to 11000 */
|
||||
continue; /* back to 2 */
|
||||
}
|
||||
if (prop[lamp] == 1)
|
||||
limit--;
|
||||
if (limit <= 30 && here(batter) && prop[batter] == 0
|
||||
&& here(lamp)) {
|
||||
rspeak(188); /* 12000 */
|
||||
prop[batter] = 1;
|
||||
if (toting(batter))
|
||||
drop(batter, loc);
|
||||
limit = limit + 2500;
|
||||
lmwarn = FALSE;
|
||||
goto l19999;
|
||||
}
|
||||
if (limit == 0) {
|
||||
limit = -1; /* 12400 */
|
||||
prop[lamp] = 0;
|
||||
rspeak(184);
|
||||
goto l19999;
|
||||
}
|
||||
if (limit < 0 && loc <= 8) {
|
||||
rspeak(185); /* 12600 */
|
||||
gaveup = TRUE;
|
||||
done(2); /* to 20000 */
|
||||
}
|
||||
if (limit <= 30) {
|
||||
if (lmwarn || !here(lamp))
|
||||
goto l19999; /* 12200 */
|
||||
lmwarn = TRUE;
|
||||
spk = 187;
|
||||
if (place[batter] == 0)
|
||||
spk = 183;
|
||||
if (prop[batter] == 1)
|
||||
spk = 189;
|
||||
rspeak(spk);
|
||||
}
|
||||
l19999: k = 43;
|
||||
if (liqloc(loc) == water)
|
||||
k = 70;
|
||||
if (weq(wd1, "enter") &&
|
||||
(weq(wd2, "strea") || weq(wd2, "water")))
|
||||
goto l2010;
|
||||
if (weq(wd1, "enter") && *wd2 != 0)
|
||||
goto l2800;
|
||||
if ((!weq(wd1, "water") && !weq(wd1, "oil"))
|
||||
|| (!weq(wd2, "plant") && !weq(wd2, "door")))
|
||||
goto l2610;
|
||||
if (at(vocab(wd2, 1, 0)))
|
||||
copystr("pour", wd2);
|
||||
|
||||
l2610: if (weq(wd1, "west"))
|
||||
if (++iwest == 10)
|
||||
rspeak(17);
|
||||
l2630: i = vocab(wd1, -1, 0);
|
||||
if (i == -1) {
|
||||
spk = 60; /* 3000 */
|
||||
if (pct(20))
|
||||
spk = 61;
|
||||
if (pct(20))
|
||||
spk = 13;
|
||||
rspeak(spk);
|
||||
goto l2600;
|
||||
}
|
||||
k = i % 1000;
|
||||
kq = i / 1000 + 1;
|
||||
switch (kq) {
|
||||
case 1:
|
||||
goto l8;
|
||||
case 2:
|
||||
goto l5000;
|
||||
case 3:
|
||||
goto l4000;
|
||||
case 4:
|
||||
goto l2010;
|
||||
default:
|
||||
bug(22);
|
||||
}
|
||||
|
||||
l8:
|
||||
switch (march()) {
|
||||
case 2:
|
||||
continue; /* i.e. goto l2 */
|
||||
case 99:
|
||||
die(99);
|
||||
goto l2000;
|
||||
default:
|
||||
bug(110);
|
||||
}
|
||||
|
||||
l2800: copystr(wd2, wd1);
|
||||
*wd2 = 0;
|
||||
goto l2610;
|
||||
|
||||
l4000: verb = k;
|
||||
spk = actspeak[verb];
|
||||
if (*wd2 != 0 && verb != say)
|
||||
goto l2800;
|
||||
if (verb == say)
|
||||
obj = *wd2;
|
||||
if (obj != 0)
|
||||
goto l4090;
|
||||
#if 0
|
||||
l4080:
|
||||
#endif
|
||||
switch (verb) {
|
||||
case 1: /* take = 8010 */
|
||||
if (atloc[loc] == 0 || links[atloc[loc]] != 0)
|
||||
goto l8000;
|
||||
for (i = 1; i <= 5; i++)
|
||||
if (dloc[i] == loc && dflag >= 2)
|
||||
goto l8000;
|
||||
obj = atloc[loc];
|
||||
goto l9010;
|
||||
case 2:
|
||||
case 3:
|
||||
case 9: /* 8000 : drop,say,wave */
|
||||
case 10:
|
||||
case 16:
|
||||
case 17: /* calm,rub,toss */
|
||||
case 19:
|
||||
case 21:
|
||||
case 28: /* find,feed,break */
|
||||
case 29: /* wake */
|
||||
l8000: printf("%s what?\n", wd1);
|
||||
obj = 0;
|
||||
goto l2600;
|
||||
case 4:
|
||||
case 6: /* 8040 open,lock */
|
||||
spk = 28;
|
||||
if (here(clam))
|
||||
obj = clam;
|
||||
if (here(oyster))
|
||||
obj = oyster;
|
||||
if (at(door))
|
||||
obj = door;
|
||||
if (at(grate))
|
||||
obj = grate;
|
||||
if (obj != 0 && here(chain))
|
||||
goto l8000;
|
||||
if (here(chain))
|
||||
obj = chain;
|
||||
if (obj == 0)
|
||||
goto l2011;
|
||||
goto l9040;
|
||||
case 5:
|
||||
goto l2009; /* nothing */
|
||||
case 7:
|
||||
goto l9070; /* on */
|
||||
case 8:
|
||||
goto l9080; /* off */
|
||||
case 11:
|
||||
goto l8000; /* walk */
|
||||
case 12:
|
||||
goto l9120; /* kill */
|
||||
case 13:
|
||||
goto l9130; /* pour */
|
||||
case 14: /* eat: 8140 */
|
||||
if (!here(food))
|
||||
goto l8000;
|
||||
l8142: destroy(food);
|
||||
spk = 72;
|
||||
goto l2011;
|
||||
case 15:
|
||||
goto l9150; /* drink */
|
||||
case 18: /* quit: 8180 */
|
||||
gaveup = yes(22, 54, 54);
|
||||
if (gaveup)
|
||||
done(2); /* 8185 */
|
||||
goto l2012;
|
||||
case 20: /* invent=8200 */
|
||||
spk = 98;
|
||||
for (i = 1; i <= 100; i++) {
|
||||
if (i != bear && toting(i)) {
|
||||
if (spk == 98)
|
||||
rspeak(99);
|
||||
blklin = FALSE;
|
||||
pspeak(i, -1);
|
||||
blklin = TRUE;
|
||||
spk = 0;
|
||||
}
|
||||
}
|
||||
if (toting(bear))
|
||||
spk = 141;
|
||||
goto l2011;
|
||||
case 22:
|
||||
goto l9220; /* fill */
|
||||
case 23:
|
||||
goto l9230; /* blast */
|
||||
case 24: /* score: 8240 */
|
||||
scoring = TRUE;
|
||||
printf("If you were to quit now, you would score");
|
||||
printf(" %d out of a possible ", score());
|
||||
printf("%d.", maxscore);
|
||||
scoring = FALSE;
|
||||
gaveup = yes(143, 54, 54);
|
||||
if (gaveup)
|
||||
done(2);
|
||||
goto l2012;
|
||||
case 25: /* foo: 8250 */
|
||||
k = vocab(wd1, 3, 0);
|
||||
spk = 42;
|
||||
if (foobar == 1 - k)
|
||||
goto l8252;
|
||||
if (foobar != 0)
|
||||
spk = 151;
|
||||
goto l2011;
|
||||
l8252: foobar = k;
|
||||
if (k != 4)
|
||||
goto l2009;
|
||||
foobar = 0;
|
||||
if (place[eggs] == plac[eggs]
|
||||
|| (toting(eggs) && loc == plac[eggs]))
|
||||
goto l2011;
|
||||
if (place[eggs] == 0 && place[troll] == 0 &&
|
||||
prop[troll] == 0)
|
||||
prop[troll] = 1;
|
||||
k = 2;
|
||||
if (here(eggs))
|
||||
k = 1;
|
||||
if (loc == plac[eggs])
|
||||
k = 0;
|
||||
move(eggs, plac[eggs]);
|
||||
pspeak(eggs, k);
|
||||
goto l2012;
|
||||
case 26: /* brief=8260 */
|
||||
spk = 156;
|
||||
abbnum = 10000;
|
||||
detail = 3;
|
||||
goto l2011;
|
||||
case 27: /* read=8270 */
|
||||
if (here(magazine))
|
||||
obj = magazine;
|
||||
if (here(tablet))
|
||||
obj = obj * 100 + tablet;
|
||||
if (here(message))
|
||||
obj = obj * 100 + message;
|
||||
if (closed && toting(oyster))
|
||||
obj = oyster;
|
||||
if (obj > 100 || obj == 0 || dark())
|
||||
goto l8000;
|
||||
goto l9270;
|
||||
case 30: /* suspend=8300 */
|
||||
spk = 201;
|
||||
if (demo)
|
||||
goto l2011;
|
||||
printf("I can suspend your adventure for you so");
|
||||
printf(" you can resume later, but\n");
|
||||
printf("you will have to wait at least");
|
||||
printf(" %d minutes before continuing.", latency);
|
||||
if (!yes(200, 54, 54))
|
||||
goto l2012;
|
||||
datime(&saveday, &savet);
|
||||
ciao(); /* Do we quit? */
|
||||
continue; /* Maybe not */
|
||||
case 31: /* hours=8310 */
|
||||
printf("Colossal cave is closed 9am-5pm Mon ");
|
||||
printf("through Fri except holidays.\n");
|
||||
goto l2012;
|
||||
default:
|
||||
bug(23);
|
||||
}
|
||||
|
||||
l4090:
|
||||
switch (verb) {
|
||||
case 1: /* take = 9010 */
|
||||
l9010: switch (trtake()) {
|
||||
case 2011:
|
||||
goto l2011;
|
||||
case 9220:
|
||||
goto l9220;
|
||||
case 2009:
|
||||
goto l2009;
|
||||
case 2012:
|
||||
goto l2012;
|
||||
default:
|
||||
bug(102);
|
||||
}
|
||||
l9020: case 2: /* drop = 9020 */
|
||||
switch (trdrop()) {
|
||||
case 2011:
|
||||
goto l2011;
|
||||
case 19000:
|
||||
done(3);
|
||||
case 2012:
|
||||
goto l2012;
|
||||
default:
|
||||
bug(105);
|
||||
}
|
||||
#if 0
|
||||
l9030:
|
||||
#endif
|
||||
case 3:
|
||||
switch (trsay()) {
|
||||
case 2012:
|
||||
goto l2012;
|
||||
case 2630:
|
||||
goto l2630;
|
||||
default:
|
||||
bug(107);
|
||||
}
|
||||
l9040: case 4:
|
||||
case 6: /* open, close */
|
||||
switch (tropen()) {
|
||||
case 2011:
|
||||
goto l2011;
|
||||
case 2010:
|
||||
goto l2010;
|
||||
default:
|
||||
bug(106);
|
||||
}
|
||||
case 5:
|
||||
goto l2009; /* nothing */
|
||||
case 7: /* on 9070 */
|
||||
l9070: if (!here(lamp))
|
||||
goto l2011;
|
||||
spk = 184;
|
||||
if (limit < 0)
|
||||
goto l2011;
|
||||
prop[lamp] = 1;
|
||||
rspeak(39);
|
||||
if (wasdark)
|
||||
goto l2000;
|
||||
goto l2012;
|
||||
|
||||
case 8: /* off */
|
||||
l9080: if (!here(lamp))
|
||||
goto l2011;
|
||||
prop[lamp] = 0;
|
||||
rspeak(40);
|
||||
if (dark())
|
||||
rspeak(16);
|
||||
goto l2012;
|
||||
|
||||
case 9: /* wave */
|
||||
if ((!toting(obj)) && (obj != rod || !toting(rod2)))
|
||||
spk = 29;
|
||||
if (obj != rod || !at(fissure) || !toting(obj) || isclosing)
|
||||
goto l2011;
|
||||
prop[fissure] = 1 - prop[fissure];
|
||||
pspeak(fissure, 2 - prop[fissure]);
|
||||
goto l2012;
|
||||
case 10:
|
||||
case 11:
|
||||
case 18: /* calm, walk, quit */
|
||||
case 24:
|
||||
case 25:
|
||||
case 26: /* score, foo, brief */
|
||||
case 30:
|
||||
case 31: /* suspend, hours */
|
||||
goto l2011;
|
||||
l9120: case 12:/* kill */
|
||||
switch (trkill()) {
|
||||
case 8000:
|
||||
goto l8000;
|
||||
case 8:
|
||||
goto l8;
|
||||
case 2011:
|
||||
goto l2011;
|
||||
case 2608:
|
||||
goto l2608;
|
||||
case 19000:
|
||||
done(3);
|
||||
default:
|
||||
bug(112);
|
||||
}
|
||||
l9130: case 13:/* pour */
|
||||
if (obj == bottle || obj == 0)
|
||||
obj = liq();
|
||||
if (obj == 0)
|
||||
goto l8000;
|
||||
if (!toting(obj))
|
||||
goto l2011;
|
||||
spk = 78;
|
||||
if (obj != oil && obj != water)
|
||||
goto l2011;
|
||||
prop[bottle] = 1;
|
||||
place[obj] = 0;
|
||||
spk = 77;
|
||||
if (!(at(plant) || at(door)))
|
||||
goto l2011;
|
||||
if (at(door)) {
|
||||
prop[door] = 0; /* 9132 */
|
||||
if (obj == oil)
|
||||
prop[door] = 1;
|
||||
spk = 113 + prop[door];
|
||||
goto l2011;
|
||||
}
|
||||
spk = 112;
|
||||
if (obj != water)
|
||||
goto l2011;
|
||||
pspeak(plant, prop[plant] + 1);
|
||||
prop[plant] = (prop[plant] + 2) % 6;
|
||||
prop[plant2] = prop[plant] / 2;
|
||||
k = null;
|
||||
goto l8;
|
||||
case 14: /* 9140 - eat */
|
||||
if (obj == food)
|
||||
goto l8142;
|
||||
if (obj == bird || obj == snake || obj == clam
|
||||
|| obj == oyster || obj == dwarf || obj == dragon
|
||||
|| obj == troll || obj == bear)
|
||||
spk = 71;
|
||||
goto l2011;
|
||||
l9150: case 15:/* 9150 - drink */
|
||||
if (obj == 0 && liqloc(loc) != water && (liq() != water
|
||||
|| !here(bottle)))
|
||||
goto l8000;
|
||||
if (obj != 0 && obj != water)
|
||||
spk = 110;
|
||||
if (spk == 110 || liq() != water || !here(bottle))
|
||||
goto l2011;
|
||||
prop[bottle] = 1;
|
||||
place[water] = 0;
|
||||
spk = 74;
|
||||
goto l2011;
|
||||
case 16: /* 9160: rub */
|
||||
if (obj != lamp)
|
||||
spk = 76;
|
||||
goto l2011;
|
||||
case 17: /* 9170: throw */
|
||||
switch (trtoss()) {
|
||||
case 2011:
|
||||
goto l2011;
|
||||
case 9020:
|
||||
goto l9020;
|
||||
case 9120:
|
||||
goto l9120;
|
||||
case 8:
|
||||
goto l8;
|
||||
case 9210:
|
||||
goto l9210;
|
||||
default:
|
||||
bug(113);
|
||||
}
|
||||
case 19:
|
||||
case 20: /* 9190: find, invent */
|
||||
if (at(obj) || (liq() == obj && at(bottle))
|
||||
|| k == liqloc(loc))
|
||||
spk = 94;
|
||||
for (i = 1; i <= 5; i++)
|
||||
if (dloc[i] == loc && dflag >= 2
|
||||
&& obj == dwarf)
|
||||
spk = 94;
|
||||
if (closed)
|
||||
spk = 138;
|
||||
if (toting(obj))
|
||||
spk = 24;
|
||||
goto l2011;
|
||||
l9210: case 21:/* feed */
|
||||
switch (trfeed()) {
|
||||
case 2011:
|
||||
goto l2011;
|
||||
default:
|
||||
bug(114);
|
||||
}
|
||||
l9220: case 22:/* fill */
|
||||
switch (trfill()) {
|
||||
case 2011:
|
||||
goto l2011;
|
||||
case 8000:
|
||||
goto l8000;
|
||||
case 9020:
|
||||
goto l9020;
|
||||
default:
|
||||
bug(115);
|
||||
}
|
||||
l9230: case 23:/* blast */
|
||||
if (prop[rod2] < 0 || !closed)
|
||||
goto l2011;
|
||||
bonus = 133;
|
||||
if (loc == 115)
|
||||
bonus = 134;
|
||||
if (here(rod2))
|
||||
bonus = 135;
|
||||
rspeak(bonus);
|
||||
done(2);
|
||||
l9270: case 27:/* read */
|
||||
if (dark())
|
||||
goto l5190;
|
||||
if (obj == magazine)
|
||||
spk = 190;
|
||||
if (obj == tablet)
|
||||
spk = 196;
|
||||
if (obj == message)
|
||||
spk = 191;
|
||||
if (obj == oyster && hinted[2] && toting(oyster))
|
||||
spk = 194;
|
||||
if (obj != oyster || hinted[2] || !toting(oyster)
|
||||
|| !closed)
|
||||
goto l2011;
|
||||
hinted[2] = yes(192, 193, 54);
|
||||
goto l2012;
|
||||
#if 0
|
||||
l9280:
|
||||
#endif
|
||||
case 28: /* break */
|
||||
if (obj == mirror)
|
||||
spk = 148;
|
||||
if (obj == vase && prop[vase] == 0) {
|
||||
spk = 198;
|
||||
if (toting(vase))
|
||||
drop(vase, loc);
|
||||
prop[vase] = 2;
|
||||
fixed[vase] = -1;
|
||||
goto l2011;
|
||||
}
|
||||
if (obj != mirror || !closed)
|
||||
goto l2011;
|
||||
rspeak(197);
|
||||
done(3);
|
||||
#if 0
|
||||
l9290:
|
||||
#endif
|
||||
case 29: /* wake */
|
||||
if (obj != dwarf || !closed)
|
||||
goto l2011;
|
||||
rspeak(199);
|
||||
done(3);
|
||||
|
||||
default:
|
||||
bug(24);
|
||||
}
|
||||
|
||||
l5000:
|
||||
obj = k;
|
||||
if (fixed[k] != loc && !here(k))
|
||||
goto l5100;
|
||||
l5010: if (*wd2 != 0)
|
||||
goto l2800;
|
||||
if (verb != 0)
|
||||
goto l4090;
|
||||
printf("What do you want to do with the %s?\n", wd1);
|
||||
goto l2600;
|
||||
l5100: if (k != grate)
|
||||
goto l5110;
|
||||
if (loc == 1 || loc == 4 || loc == 7)
|
||||
k = depression;
|
||||
if (loc > 9 && loc < 15)
|
||||
k = entrance;
|
||||
if (k != grate)
|
||||
goto l8;
|
||||
l5110: if (k != dwarf)
|
||||
goto l5120;
|
||||
for (i = 1; i <= 5; i++)
|
||||
if (dloc[i] == loc && dflag >= 2)
|
||||
goto l5010;
|
||||
l5120: if ((liq() == k && here(bottle)) || k == liqloc(loc))
|
||||
goto l5010;
|
||||
if (obj != plant || !at(plant2) || prop[plant2] == 0)
|
||||
goto l5130;
|
||||
obj = plant2;
|
||||
goto l5010;
|
||||
l5130: if (obj != knife || knfloc != loc)
|
||||
goto l5140;
|
||||
knfloc = -1;
|
||||
spk = 116;
|
||||
goto l2011;
|
||||
l5140: if (obj != rod || !here(rod2))
|
||||
goto l5190;
|
||||
obj = rod2;
|
||||
goto l5010;
|
||||
l5190: if ((verb == find || verb == invent) && *wd2 == 0)
|
||||
goto l5010;
|
||||
printf("I see no %s here\n", wd1);
|
||||
goto l2012;
|
||||
}
|
||||
}
|
868
games/adventure/save.c
Normal file
868
games/adventure/save.c
Normal file
|
@ -0,0 +1,868 @@
|
|||
/* $NetBSD: save.c,v 1.13 2012/01/08 18:16:00 dholland Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* The game adventure was originally written in Fortran by Will Crowther
|
||||
* and Don Woods. It was later translated to C and enhanced by Jim
|
||||
* Gillogly. This code is derived from software contributed to Berkeley
|
||||
* by Jim Gillogly at The Rand Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)save.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: save.c,v 1.13 2012/01/08 18:16:00 dholland Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <err.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "hdr.h"
|
||||
#include "extern.h"
|
||||
|
||||
struct savefile {
|
||||
FILE *f;
|
||||
const char *name;
|
||||
bool warned;
|
||||
unsigned bintextpos;
|
||||
uint32_t key;
|
||||
struct crcstate crc;
|
||||
unsigned char pad[8];
|
||||
unsigned padpos;
|
||||
};
|
||||
|
||||
#define BINTEXT_WIDTH 60
|
||||
#define FORMAT_VERSION 2
|
||||
#define FORMAT_VERSION_NOSUM 1
|
||||
static const char header[] = "Adventure save file\n";
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// base16 output encoding
|
||||
|
||||
/*
|
||||
* Map 16 plain values into 90 coded values and back.
|
||||
*/
|
||||
|
||||
static const char coding[90] =
|
||||
"Db.GOyT]7a6zpF(c*5H9oK~0[WVAg&kR)ml,2^q-1Y3v+"
|
||||
"X/=JirZL$C>_N?:}B{dfnsxU<@MQ%8|P!4h`ESt;euwIj"
|
||||
;
|
||||
|
||||
static int
|
||||
readletter(char letter, unsigned char *ret)
|
||||
{
|
||||
const char *s;
|
||||
|
||||
s = strchr(coding, letter);
|
||||
if (s == NULL) {
|
||||
return 1;
|
||||
}
|
||||
*ret = (s - coding) % 16;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char
|
||||
writeletter(unsigned char nibble)
|
||||
{
|
||||
unsigned code;
|
||||
|
||||
assert(nibble < 16);
|
||||
do {
|
||||
code = (16 * (random() % 6)) + nibble;
|
||||
} while (code >= 90);
|
||||
return coding[code];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// savefile
|
||||
|
||||
/*
|
||||
* Open a savefile.
|
||||
*/
|
||||
static struct savefile *
|
||||
savefile_open(const char *name, bool forwrite)
|
||||
{
|
||||
struct savefile *sf;
|
||||
|
||||
sf = malloc(sizeof(*sf));
|
||||
if (sf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sf->f = fopen(name, forwrite ? "w" : "r");
|
||||
if (sf->f == NULL) {
|
||||
free(sf);
|
||||
fprintf(stderr,
|
||||
"Hmm. The name \"%s\" appears to be magically blocked.\n",
|
||||
name);
|
||||
return NULL;
|
||||
}
|
||||
sf->name = name;
|
||||
sf->warned = false;
|
||||
sf->bintextpos = 0;
|
||||
sf->key = 0;
|
||||
crc_start(&sf->crc);
|
||||
memset(sf->pad, 0, sizeof(sf->pad));
|
||||
sf->padpos = 0;
|
||||
return sf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Raw read.
|
||||
*/
|
||||
static int
|
||||
savefile_rawread(struct savefile *sf, void *data, size_t len)
|
||||
{
|
||||
size_t result;
|
||||
|
||||
result = fread(data, 1, len, sf->f);
|
||||
if (result != len || ferror(sf->f)) {
|
||||
fprintf(stderr, "Oops: error reading %s.\n", sf->name);
|
||||
sf->warned = true;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Raw write.
|
||||
*/
|
||||
static int
|
||||
savefile_rawwrite(struct savefile *sf, const void *data, size_t len)
|
||||
{
|
||||
size_t result;
|
||||
|
||||
result = fwrite(data, 1, len, sf->f);
|
||||
if (result != len || ferror(sf->f)) {
|
||||
fprintf(stderr, "Oops: error writing %s.\n", sf->name);
|
||||
sf->warned = true;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close a savefile.
|
||||
*/
|
||||
static int
|
||||
savefile_close(struct savefile *sf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (sf->bintextpos > 0) {
|
||||
savefile_rawwrite(sf, "\n", 1);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
if (fclose(sf->f)) {
|
||||
if (!sf->warned) {
|
||||
fprintf(stderr, "Oops: error on %s.\n", sf->name);
|
||||
}
|
||||
ret = 1;
|
||||
}
|
||||
free(sf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read encoded binary data, discarding any whitespace that appears.
|
||||
*/
|
||||
static int
|
||||
savefile_bintextread(struct savefile *sf, void *data, size_t len)
|
||||
{
|
||||
size_t pos;
|
||||
unsigned char *udata;
|
||||
int ch;
|
||||
|
||||
udata = data;
|
||||
pos = 0;
|
||||
while (pos < len) {
|
||||
ch = fgetc(sf->f);
|
||||
if (ch == EOF || ferror(sf->f)) {
|
||||
fprintf(stderr, "Oops: error reading %s.\n", sf->name);
|
||||
sf->warned = true;
|
||||
return 1;
|
||||
}
|
||||
if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') {
|
||||
continue;
|
||||
}
|
||||
udata[pos++] = ch;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read binary data, decoding from text using readletter().
|
||||
*/
|
||||
static int
|
||||
savefile_binread(struct savefile *sf, void *data, size_t len)
|
||||
{
|
||||
unsigned char buf[64];
|
||||
unsigned char *udata;
|
||||
unsigned char val1, val2;
|
||||
size_t pos, amt, i;
|
||||
|
||||
udata = data;
|
||||
pos = 0;
|
||||
while (pos < len) {
|
||||
amt = len - pos;
|
||||
if (amt > sizeof(buf) / 2) {
|
||||
amt = sizeof(buf) / 2;
|
||||
}
|
||||
if (savefile_bintextread(sf, buf, amt*2)) {
|
||||
return 1;
|
||||
}
|
||||
for (i=0; i<amt; i++) {
|
||||
if (readletter(buf[i*2], &val1)) {
|
||||
return 1;
|
||||
}
|
||||
if (readletter(buf[i*2 + 1], &val2)) {
|
||||
return 1;
|
||||
}
|
||||
udata[pos++] = val1 * 16 + val2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write encoded binary data, inserting newlines to get a neatly
|
||||
* formatted block.
|
||||
*/
|
||||
static int
|
||||
savefile_bintextwrite(struct savefile *sf, const void *data, size_t len)
|
||||
{
|
||||
size_t pos, amt;
|
||||
const unsigned char *udata;
|
||||
|
||||
udata = data;
|
||||
pos = 0;
|
||||
while (pos < len) {
|
||||
amt = BINTEXT_WIDTH - sf->bintextpos;
|
||||
if (amt > len - pos) {
|
||||
amt = len - pos;
|
||||
}
|
||||
if (savefile_rawwrite(sf, udata + pos, amt)) {
|
||||
return 1;
|
||||
}
|
||||
pos += amt;
|
||||
sf->bintextpos += amt;
|
||||
if (sf->bintextpos >= BINTEXT_WIDTH) {
|
||||
savefile_rawwrite(sf, "\n", 1);
|
||||
sf->bintextpos = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write binary data, encoding as text using writeletter().
|
||||
*/
|
||||
static int
|
||||
savefile_binwrite(struct savefile *sf, const void *data, size_t len)
|
||||
{
|
||||
unsigned char buf[64];
|
||||
const unsigned char *udata;
|
||||
size_t pos, bpos;
|
||||
unsigned char byte;
|
||||
|
||||
udata = data;
|
||||
pos = 0;
|
||||
bpos = 0;
|
||||
while (pos < len) {
|
||||
byte = udata[pos++];
|
||||
buf[bpos++] = writeletter(byte >> 4);
|
||||
buf[bpos++] = writeletter(byte & 0xf);
|
||||
if (bpos >= sizeof(buf)) {
|
||||
if (savefile_bintextwrite(sf, buf, bpos)) {
|
||||
return 1;
|
||||
}
|
||||
bpos = 0;
|
||||
}
|
||||
}
|
||||
if (savefile_bintextwrite(sf, buf, bpos)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lightweight "encryption" for save files. This is not meant to
|
||||
* be secure and wouldn't be even if we didn't write the decrypt
|
||||
* key to the beginning of the save file; it's just meant to be
|
||||
* enough to discourage casual cheating.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Make cheesy hash of buf[0..buflen]. Note: buf and outhash may overlap.
|
||||
*/
|
||||
static void
|
||||
hash(const void *data, size_t datalen, unsigned char *out, size_t outlen)
|
||||
{
|
||||
const unsigned char *udata;
|
||||
size_t i;
|
||||
uint64_t val;
|
||||
const unsigned char *uval;
|
||||
size_t valpos;
|
||||
|
||||
udata = data;
|
||||
val = 0;
|
||||
for (i=0; i<datalen; i++) {
|
||||
val = val ^ 0xbadc0ffee;
|
||||
val = (val << 4) | (val >> 60);
|
||||
val += udata[i] ^ 0xbeef;
|
||||
}
|
||||
|
||||
uval = (unsigned char *)&val;
|
||||
valpos = 0;
|
||||
for (i=0; i<outlen; i++) {
|
||||
out[i] = uval[valpos++];
|
||||
if (valpos >= sizeof(val)) {
|
||||
valpos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the "encryption" key.
|
||||
*/
|
||||
static void
|
||||
savefile_key(struct savefile *sf, uint32_t key)
|
||||
{
|
||||
sf->key = 0;
|
||||
crc_start(&sf->crc);
|
||||
hash(&sf->key, sizeof(sf->key), sf->pad, sizeof(sf->pad));
|
||||
sf->padpos = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get an "encryption" pad byte. This forms a stream "cipher" that we
|
||||
* xor with the plaintext save data.
|
||||
*/
|
||||
static unsigned char
|
||||
savefile_getpad(struct savefile *sf)
|
||||
{
|
||||
unsigned char ret;
|
||||
|
||||
ret = sf->pad[sf->padpos++];
|
||||
if (sf->padpos >= sizeof(sf->pad)) {
|
||||
hash(sf->pad, sizeof(sf->pad), sf->pad, sizeof(sf->pad));
|
||||
sf->padpos = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read "encrypted" data.
|
||||
*/
|
||||
static int
|
||||
savefile_cread(struct savefile *sf, void *data, size_t len)
|
||||
{
|
||||
char buf[64];
|
||||
unsigned char *udata;
|
||||
size_t pos, amt, i;
|
||||
unsigned char ch;
|
||||
|
||||
udata = data;
|
||||
pos = 0;
|
||||
while (pos < len) {
|
||||
amt = len - pos;
|
||||
if (amt > sizeof(buf)) {
|
||||
amt = sizeof(buf);
|
||||
}
|
||||
if (savefile_binread(sf, buf, amt)) {
|
||||
return 1;
|
||||
}
|
||||
for (i=0; i<amt; i++) {
|
||||
ch = buf[i];
|
||||
ch ^= savefile_getpad(sf);
|
||||
udata[pos + i] = ch;
|
||||
}
|
||||
pos += amt;
|
||||
}
|
||||
crc_add(&sf->crc, data, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write "encrypted" data.
|
||||
*/
|
||||
static int
|
||||
savefile_cwrite(struct savefile *sf, const void *data, size_t len)
|
||||
{
|
||||
char buf[64];
|
||||
const unsigned char *udata;
|
||||
size_t pos, amt, i;
|
||||
unsigned char ch;
|
||||
|
||||
udata = data;
|
||||
pos = 0;
|
||||
while (pos < len) {
|
||||
amt = len - pos;
|
||||
if (amt > sizeof(buf)) {
|
||||
amt = sizeof(buf);
|
||||
}
|
||||
for (i=0; i<amt; i++) {
|
||||
ch = udata[pos + i];
|
||||
ch ^= savefile_getpad(sf);
|
||||
buf[i] = ch;
|
||||
}
|
||||
if (savefile_binwrite(sf, buf, amt)) {
|
||||
return 1;
|
||||
}
|
||||
pos += amt;
|
||||
}
|
||||
crc_add(&sf->crc, data, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// compat for old save files
|
||||
|
||||
struct compat_saveinfo {
|
||||
void *address;
|
||||
int width;
|
||||
};
|
||||
|
||||
static const struct compat_saveinfo compat_savearray[] =
|
||||
{
|
||||
{&abbnum, sizeof(abbnum)},
|
||||
{&attack, sizeof(attack)},
|
||||
{&blklin, sizeof(blklin)},
|
||||
{&bonus, sizeof(bonus)},
|
||||
{&chloc, sizeof(chloc)},
|
||||
{&chloc2, sizeof(chloc2)},
|
||||
{&clock1, sizeof(clock1)},
|
||||
{&clock2, sizeof(clock2)},
|
||||
{&closed, sizeof(closed)},
|
||||
{&isclosing, sizeof(isclosing)},
|
||||
{&daltloc, sizeof(daltloc)},
|
||||
{&demo, sizeof(demo)},
|
||||
{&detail, sizeof(detail)},
|
||||
{&dflag, sizeof(dflag)},
|
||||
{&dkill, sizeof(dkill)},
|
||||
{&dtotal, sizeof(dtotal)},
|
||||
{&foobar, sizeof(foobar)},
|
||||
{&gaveup, sizeof(gaveup)},
|
||||
{&holding, sizeof(holding)},
|
||||
{&iwest, sizeof(iwest)},
|
||||
{&k, sizeof(k)},
|
||||
{&k2, sizeof(k2)},
|
||||
{&knfloc, sizeof(knfloc)},
|
||||
{&kq, sizeof(kq)},
|
||||
{&latency, sizeof(latency)},
|
||||
{&limit, sizeof(limit)},
|
||||
{&lmwarn, sizeof(lmwarn)},
|
||||
{&loc, sizeof(loc)},
|
||||
{&maxdie, sizeof(maxdie)},
|
||||
{&maxscore, sizeof(maxscore)},
|
||||
{&newloc, sizeof(newloc)},
|
||||
{&numdie, sizeof(numdie)},
|
||||
{&obj, sizeof(obj)},
|
||||
{&oldloc2, sizeof(oldloc2)},
|
||||
{&oldloc, sizeof(oldloc)},
|
||||
{&panic, sizeof(panic)},
|
||||
{&saveday, sizeof(saveday)},
|
||||
{&savet, sizeof(savet)},
|
||||
{&scoring, sizeof(scoring)},
|
||||
{&spk, sizeof(spk)},
|
||||
{&stick, sizeof(stick)},
|
||||
{&tally, sizeof(tally)},
|
||||
{&tally2, sizeof(tally2)},
|
||||
{&tkk, sizeof(tkk)},
|
||||
{&turns, sizeof(turns)},
|
||||
{&verb, sizeof(verb)},
|
||||
{&wd1, sizeof(wd1)},
|
||||
{&wd2, sizeof(wd2)},
|
||||
{&wasdark, sizeof(wasdark)},
|
||||
{&yea, sizeof(yea)},
|
||||
{atloc, sizeof(atloc)},
|
||||
{dloc, sizeof(dloc)},
|
||||
{dseen, sizeof(dseen)},
|
||||
{fixed, sizeof(fixed)},
|
||||
{hinted, sizeof(hinted)},
|
||||
{links, sizeof(links)},
|
||||
{odloc, sizeof(odloc)},
|
||||
{place, sizeof(place)},
|
||||
{prop, sizeof(prop)},
|
||||
{tk, sizeof(tk)},
|
||||
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
static int
|
||||
compat_restore(const char *infile)
|
||||
{
|
||||
FILE *in;
|
||||
const struct compat_saveinfo *p;
|
||||
char *s;
|
||||
long sum, cksum = 0;
|
||||
int i;
|
||||
struct crcstate crc;
|
||||
|
||||
if ((in = fopen(infile, "rb")) == NULL) {
|
||||
fprintf(stderr,
|
||||
"Hmm. The file \"%s\" appears to be magically blocked.\n",
|
||||
infile);
|
||||
return 1;
|
||||
}
|
||||
fread(&sum, sizeof(sum), 1, in); /* Get the seed */
|
||||
srandom((int) sum);
|
||||
for (p = compat_savearray; p->address != NULL; p++) {
|
||||
fread(p->address, p->width, 1, in);
|
||||
for (s = p->address, i = 0; i < p->width; i++, s++)
|
||||
*s = (*s ^ random()) & 0xFF; /* Lightly decrypt */
|
||||
}
|
||||
fclose(in);
|
||||
|
||||
crc_start(&crc); /* See if she cheated */
|
||||
for (p = compat_savearray; p->address != NULL; p++)
|
||||
crc_add(&crc, p->address, p->width);
|
||||
cksum = crc_get(&crc);
|
||||
if (sum != cksum) /* Tsk tsk */
|
||||
return 2; /* Altered the file */
|
||||
/* We successfully restored, so this really was a save file */
|
||||
|
||||
/*
|
||||
* The above code loads these from disk even though they're
|
||||
* pointers. Null them out and hope we don't crash on them
|
||||
* later; that's better than having them be garbage.
|
||||
*/
|
||||
tkk = NULL;
|
||||
wd1 = NULL;
|
||||
wd2 = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// save + restore
|
||||
|
||||
static int *const save_ints[] = {
|
||||
&abbnum,
|
||||
&attack,
|
||||
&blklin,
|
||||
&bonus,
|
||||
&chloc,
|
||||
&chloc2,
|
||||
&clock1,
|
||||
&clock2,
|
||||
&closed,
|
||||
&isclosing,
|
||||
&daltloc,
|
||||
&demo,
|
||||
&detail,
|
||||
&dflag,
|
||||
&dkill,
|
||||
&dtotal,
|
||||
&foobar,
|
||||
&gaveup,
|
||||
&holding,
|
||||
&iwest,
|
||||
&k,
|
||||
&k2,
|
||||
&knfloc,
|
||||
&kq,
|
||||
&latency,
|
||||
&limit,
|
||||
&lmwarn,
|
||||
&loc,
|
||||
&maxdie,
|
||||
&maxscore,
|
||||
&newloc,
|
||||
&numdie,
|
||||
&obj,
|
||||
&oldloc2,
|
||||
&oldloc,
|
||||
&panic,
|
||||
&saveday,
|
||||
&savet,
|
||||
&scoring,
|
||||
&spk,
|
||||
&stick,
|
||||
&tally,
|
||||
&tally2,
|
||||
&turns,
|
||||
&verb,
|
||||
&wasdark,
|
||||
&yea,
|
||||
};
|
||||
static const unsigned num_save_ints = __arraycount(save_ints);
|
||||
|
||||
#define INTARRAY(sym) { sym, __arraycount(sym) }
|
||||
|
||||
static const struct {
|
||||
int *ptr;
|
||||
unsigned num;
|
||||
} save_intarrays[] = {
|
||||
INTARRAY(atloc),
|
||||
INTARRAY(dseen),
|
||||
INTARRAY(dloc),
|
||||
INTARRAY(odloc),
|
||||
INTARRAY(fixed),
|
||||
INTARRAY(hinted),
|
||||
INTARRAY(links),
|
||||
INTARRAY(place),
|
||||
INTARRAY(prop),
|
||||
INTARRAY(tk),
|
||||
};
|
||||
static const unsigned num_save_intarrays = __arraycount(save_intarrays);
|
||||
|
||||
#undef INTARRAY
|
||||
|
||||
#if 0
|
||||
static const struct {
|
||||
void *ptr;
|
||||
size_t len;
|
||||
} save_blobs[] = {
|
||||
{ &wd1, sizeof(wd1) },
|
||||
{ &wd2, sizeof(wd2) },
|
||||
{ &tkk, sizeof(tkk) },
|
||||
};
|
||||
static const unsigned num_save_blobs = __arraycount(save_blobs);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Write out a save file. Returns nonzero on error.
|
||||
*/
|
||||
int
|
||||
save(const char *outfile)
|
||||
{
|
||||
struct savefile *sf;
|
||||
struct timespec now;
|
||||
uint32_t key, writeable_key;
|
||||
uint32_t version;
|
||||
unsigned i, j, n;
|
||||
uint32_t val, sum;
|
||||
|
||||
sf = savefile_open(outfile, true);
|
||||
if (sf == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (savefile_rawwrite(sf, header, strlen(header))) {
|
||||
savefile_close(sf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
version = htonl(FORMAT_VERSION);
|
||||
if (savefile_binwrite(sf, &version, sizeof(version))) {
|
||||
savefile_close(sf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &now);
|
||||
key = (uint32_t)(now.tv_sec & 0xffffffff) ^ (uint32_t)(now.tv_nsec);
|
||||
|
||||
writeable_key = htonl(key);
|
||||
if (savefile_binwrite(sf, &writeable_key, sizeof(writeable_key))) {
|
||||
savefile_close(sf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* other parts of the code may depend on us doing this here */
|
||||
srandom(key);
|
||||
|
||||
savefile_key(sf, key);
|
||||
|
||||
/*
|
||||
* Integers
|
||||
*/
|
||||
for (i=0; i<num_save_ints; i++) {
|
||||
val = *(save_ints[i]);
|
||||
val = htonl(val);
|
||||
if (savefile_cwrite(sf, &val, sizeof(val))) {
|
||||
savefile_close(sf);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Arrays of integers
|
||||
*/
|
||||
for (i=0; i<num_save_intarrays; i++) {
|
||||
n = save_intarrays[i].num;
|
||||
for (j=0; j<n; j++) {
|
||||
val = save_intarrays[i].ptr[j];
|
||||
val = htonl(val);
|
||||
if (savefile_cwrite(sf, &val, sizeof(val))) {
|
||||
savefile_close(sf);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Blobs
|
||||
*/
|
||||
for (i=0; i<num_save_blobs; i++) {
|
||||
if (savefile_cwrite(sf, save_blobs[i].ptr, save_blobs[i].len)) {
|
||||
savefile_close(sf);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
sum = htonl(crc_get(&sf->crc));
|
||||
if (savefile_binwrite(sf, &sum, sizeof(&sum))) {
|
||||
savefile_close(sf);
|
||||
return 1;
|
||||
}
|
||||
savefile_close(sf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read in a save file. Returns nonzero on error.
|
||||
*/
|
||||
int
|
||||
restore(const char *infile)
|
||||
{
|
||||
struct savefile *sf;
|
||||
char buf[sizeof(header)];
|
||||
size_t headersize = strlen(header);
|
||||
uint32_t version, key, sum;
|
||||
unsigned i, j, n;
|
||||
uint32_t val;
|
||||
bool skipsum = false;
|
||||
|
||||
sf = savefile_open(infile, false);
|
||||
if (sf == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (savefile_rawread(sf, buf, headersize)) {
|
||||
savefile_close(sf);
|
||||
return 1;
|
||||
}
|
||||
buf[headersize] = 0;
|
||||
if (strcmp(buf, header) != 0) {
|
||||
savefile_close(sf);
|
||||
fprintf(stderr, "Oh dear, that isn't one of my save files.\n");
|
||||
fprintf(stderr,
|
||||
"Trying the Olde Waye; this myte notte Worke.\n");
|
||||
return compat_restore(infile);
|
||||
}
|
||||
|
||||
if (savefile_binread(sf, &version, sizeof(version))) {
|
||||
savefile_close(sf);
|
||||
return 1;
|
||||
}
|
||||
version = ntohl(version);
|
||||
switch (version) {
|
||||
case FORMAT_VERSION:
|
||||
break;
|
||||
case FORMAT_VERSION_NOSUM:
|
||||
skipsum = true;
|
||||
break;
|
||||
default:
|
||||
savefile_close(sf);
|
||||
fprintf(stderr,
|
||||
"Oh dear, that file must be from the future. I don't know"
|
||||
" how to read it!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (savefile_binread(sf, &key, sizeof(key))) {
|
||||
savefile_close(sf);
|
||||
return 1;
|
||||
}
|
||||
key = ntohl(key);
|
||||
savefile_key(sf, key);
|
||||
|
||||
/* other parts of the code may depend on us doing this here */
|
||||
srandom(key);
|
||||
|
||||
/*
|
||||
* Integers
|
||||
*/
|
||||
for (i=0; i<num_save_ints; i++) {
|
||||
if (savefile_cread(sf, &val, sizeof(val))) {
|
||||
savefile_close(sf);
|
||||
return 1;
|
||||
}
|
||||
val = ntohl(val);
|
||||
*(save_ints[i]) = val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Arrays of integers
|
||||
*/
|
||||
for (i=0; i<num_save_intarrays; i++) {
|
||||
n = save_intarrays[i].num;
|
||||
for (j=0; j<n; j++) {
|
||||
if (savefile_cread(sf, &val, sizeof(val))) {
|
||||
savefile_close(sf);
|
||||
return 1;
|
||||
}
|
||||
val = ntohl(val);
|
||||
save_intarrays[i].ptr[j] = val;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Blobs
|
||||
*/
|
||||
for (i=0; i<num_save_blobs; i++) {
|
||||
if (savefile_cread(sf, save_blobs[i].ptr, save_blobs[i].len)) {
|
||||
savefile_close(sf);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (savefile_binread(sf, &sum, sizeof(&sum))) {
|
||||
savefile_close(sf);
|
||||
return 1;
|
||||
}
|
||||
sum = ntohl(sum);
|
||||
/* See if she cheated */
|
||||
if (!skipsum && sum != crc_get(&sf->crc)) {
|
||||
/* Tsk tsk, altered the file */
|
||||
savefile_close(sf);
|
||||
return 2;
|
||||
}
|
||||
savefile_close(sf);
|
||||
|
||||
/* Load theoretically invalidates these */
|
||||
tkk = NULL;
|
||||
wd1 = NULL;
|
||||
wd2 = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
128
games/adventure/setup.c
Normal file
128
games/adventure/setup.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
/* $NetBSD: setup.c,v 1.11 2005/07/01 00:03:36 jmc Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jim Gillogly at The Rand Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] = "@(#) Copyright (c) 1991, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)setup.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
static char rcsid[] = "$NetBSD: setup.c,v 1.11 2005/07/01 00:03:36 jmc Exp $";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* Setup: keep the structure of the original Adventure port, but use an
|
||||
* internal copy of the data file, serving as a sort of virtual disk. It's
|
||||
* lightly encrypted to prevent casual snooping of the executable.
|
||||
*
|
||||
* Also do appropriate things to tabs so that bogus editors will do the right
|
||||
* thing with the data file.
|
||||
*
|
||||
*/
|
||||
|
||||
#define SIG1 " * Jim Gillogly"
|
||||
#define SIG2 " * Sterday, 6 Thrimidge S.R. 1993, 15:24"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "hdr.h" /* SEED lives in there; keep them coordinated. */
|
||||
|
||||
#define USAGE "Usage: setup file > data.c (file is typically glorkz)\n"
|
||||
|
||||
#define YES 1
|
||||
#define NO 0
|
||||
|
||||
#define LINE 10 /* How many values do we get on a line? */
|
||||
|
||||
int main(int, char *[]);
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
FILE *infile;
|
||||
int c, count, linestart;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, USAGE);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((infile = fopen(argv[1], "r")) == NULL) {
|
||||
fprintf(stderr, "Can't read file %s: %s\n", argv[1],
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
puts("/*\n * data.c: created by setup from the ascii data file.");
|
||||
puts(SIG1);
|
||||
puts(SIG2);
|
||||
puts(" */");
|
||||
printf("\n\nchar data_file[] =\n{");
|
||||
srandom(SEED);
|
||||
count = 0;
|
||||
linestart = YES;
|
||||
|
||||
while ((c = getc(infile)) != EOF) {
|
||||
if (linestart && c == ' ') { /* Convert first spaces to tab */
|
||||
printf("0x%02x,",
|
||||
(unsigned int)('\t' ^ random()) & 0xFF);
|
||||
while ((c = getc(infile)) == ' ' && c != EOF);
|
||||
/* Drop the non-whitespace character through */
|
||||
linestart = NO;
|
||||
}
|
||||
switch (c) {
|
||||
case '\t':
|
||||
linestart = NO; /* Don't need to convert spaces */
|
||||
break;
|
||||
case '\n':
|
||||
linestart = YES; /* Ready to convert spaces
|
||||
* again */
|
||||
break;
|
||||
}
|
||||
if (count++ % LINE == 0) /* Finished a line? */
|
||||
printf("\n\t");
|
||||
printf("0x%02x,", (unsigned int)(c ^ random()) & 0xFF);
|
||||
}
|
||||
puts("\n\t0\n};");
|
||||
fclose(infile);
|
||||
fflush(stdout);
|
||||
if (ferror(stdout)) {
|
||||
perror("error writing standard output");
|
||||
exit(1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
1057
games/adventure/subr.c
Normal file
1057
games/adventure/subr.c
Normal file
File diff suppressed because it is too large
Load diff
218
games/adventure/vocab.c
Normal file
218
games/adventure/vocab.c
Normal file
|
@ -0,0 +1,218 @@
|
|||
/* $NetBSD: vocab.c,v 1.15 2009/08/25 06:56:52 dholland Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* The game adventure was originally written in Fortran by Will Crowther
|
||||
* and Don Woods. It was later translated to C and enhanced by Jim
|
||||
* Gillogly. This code is derived from software contributed to Berkeley
|
||||
* by Jim Gillogly at The Rand Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)vocab.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: vocab.c,v 1.15 2009/08/25 06:56:52 dholland Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
/* Re-coding of advent in C: data structure routines */
|
||||
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "hdr.h"
|
||||
#include "extern.h"
|
||||
|
||||
void
|
||||
destroy(int object)
|
||||
{
|
||||
move(object, 0);
|
||||
}
|
||||
|
||||
void
|
||||
juggle(int object)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
i = place[object];
|
||||
j = fixed[object];
|
||||
move(object, i);
|
||||
move(object + 100, j);
|
||||
}
|
||||
|
||||
void
|
||||
move(int object, int where)
|
||||
{
|
||||
int from;
|
||||
|
||||
if (object <= 100)
|
||||
from = place[object];
|
||||
else
|
||||
from = fixed[object - 100];
|
||||
if (from > 0 && from <= 300)
|
||||
carry(object, from);
|
||||
drop(object, where);
|
||||
}
|
||||
|
||||
int
|
||||
put(int object, int where, int pval)
|
||||
{
|
||||
move(object, where);
|
||||
return (-1 - pval);
|
||||
}
|
||||
|
||||
void
|
||||
carry(int object, int where)
|
||||
{
|
||||
int temp;
|
||||
|
||||
if (object <= 100) {
|
||||
if (place[object] == -1)
|
||||
return;
|
||||
place[object] = -1;
|
||||
holding++;
|
||||
}
|
||||
if (atloc[where] == object) {
|
||||
atloc[where] = links[object];
|
||||
return;
|
||||
}
|
||||
for (temp = atloc[where]; links[temp] != object; temp = links[temp]);
|
||||
links[temp] = links[object];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
drop(int object, int where)
|
||||
{
|
||||
if (object > 100)
|
||||
fixed[object - 100] = where;
|
||||
else {
|
||||
if (place[object] == -1)
|
||||
holding--;
|
||||
place[object] = where;
|
||||
}
|
||||
if (where <= 0)
|
||||
return;
|
||||
links[object] = atloc[where];
|
||||
atloc[where] = object;
|
||||
}
|
||||
|
||||
/* look up or store a word */
|
||||
/* -2 for store, -1 for user word, >=0 for canned lookup */
|
||||
/* used for storing only */
|
||||
int
|
||||
vocab(const char *word, int type, int value)
|
||||
{
|
||||
int adr;
|
||||
const char *s;
|
||||
char *t;
|
||||
int hash, i;
|
||||
struct hashtab *h;
|
||||
|
||||
for (hash = 0, s = word, i = 0; i < 5 && *s; i++) /* some kind of hash*/
|
||||
hash += *s++; /* add all chars in the word */
|
||||
hash = (hash * 3719) & 077777; /* pulled that one out of a hat */
|
||||
hash %= HTSIZE; /* put it into range of table */
|
||||
|
||||
for (adr = hash;; adr++) { /* look for entry in table */
|
||||
if (adr == HTSIZE)
|
||||
adr = 0;/* wrap around */
|
||||
h = &voc[adr]; /* point at the entry */
|
||||
switch (type) {
|
||||
case -2: /* fill in entry */
|
||||
if (h->val) /* already got an entry? */
|
||||
goto exitloop2;
|
||||
h->val = value;
|
||||
h->atab = malloc(length(word));
|
||||
if (h->atab == NULL)
|
||||
err(1, NULL);
|
||||
for (s = word, t = h->atab; *s;)
|
||||
*t++ = *s++ ^ '=';
|
||||
*t = 0 ^ '=';
|
||||
/* encrypt slightly to thwart core reader */
|
||||
/* printf("Stored \"%s\" (%d ch) as entry %d\n", */
|
||||
/* word, length(word), adr); */
|
||||
return (0); /* entry unused */
|
||||
case -1: /* looking up user word */
|
||||
if (h->val == 0)
|
||||
return (-1); /* not found */
|
||||
for (s = word, t = h->atab; *t ^ '=';)
|
||||
if ((*s++ ^ '=') != *t++)
|
||||
goto exitloop2;
|
||||
if ((*s ^ '=') != *t && s - word < 5)
|
||||
goto exitloop2;
|
||||
/* the word matched o.k. */
|
||||
return (h->val);
|
||||
default: /* looking up known word */
|
||||
if (h->val == 0)
|
||||
errx(1,"Unable to find %s in vocab", word);
|
||||
for (s = word, t = h->atab; *t ^ '=';)
|
||||
if ((*s++ ^ '=') != *t++)
|
||||
goto exitloop2;
|
||||
/* the word matched o.k. */
|
||||
if (h->val / 1000 != type)
|
||||
continue;
|
||||
return (h->val % 1000);
|
||||
}
|
||||
|
||||
exitloop2: /* hashed entry does not match */
|
||||
if (adr + 1 == hash || hash == 0)
|
||||
errx(1,"Hash table overflow");
|
||||
}
|
||||
}
|
||||
|
||||
/* print hash table (for debugging) */
|
||||
static __unused void
|
||||
prht(void)
|
||||
{
|
||||
int i, j, l;
|
||||
char *c;
|
||||
struct hashtab *h;
|
||||
for (i = 0; i < HTSIZE / 10 + 1; i++) {
|
||||
printf("%4d", i * 10);
|
||||
for (j = 0; j < 10; j++) {
|
||||
if (i * 10 + j >= HTSIZE)
|
||||
break;
|
||||
h = &voc[i * 10 + j];
|
||||
putchar(' ');
|
||||
if (h->val == 0) {
|
||||
printf("-----");
|
||||
continue;
|
||||
}
|
||||
for (l = 0, c = h->atab; l < 5; l++)
|
||||
if ((*c ^ '='))
|
||||
putchar(*c++ ^ '=');
|
||||
else
|
||||
putchar(' ');
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
162
games/adventure/wizard.c
Normal file
162
games/adventure/wizard.c
Normal file
|
@ -0,0 +1,162 @@
|
|||
/* $NetBSD: wizard.c,v 1.16 2012/10/12 15:41:10 dholland Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* The game adventure was originally written in Fortran by Will Crowther
|
||||
* and Don Woods. It was later translated to C and enhanced by Jim
|
||||
* Gillogly. This code is derived from software contributed to Berkeley
|
||||
* by Jim Gillogly at The Rand Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)wizard.c 8.1 (Berkeley) 6/2/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: wizard.c,v 1.16 2012/10/12 15:41:10 dholland Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
/* Re-coding of advent in C: privileged operations */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "hdr.h"
|
||||
#include "extern.h"
|
||||
|
||||
static int wizard(void);
|
||||
|
||||
void
|
||||
datime(int *d, int *t)
|
||||
{
|
||||
time_t tvec;
|
||||
struct tm *tptr;
|
||||
|
||||
time(&tvec);
|
||||
tptr = localtime(&tvec);
|
||||
/* day since 1977 (mod leap) */
|
||||
*d = (tptr->tm_yday + 365 * (tptr->tm_year - 77)
|
||||
+ (tptr->tm_year - 77) / 4 - (tptr->tm_year - 1) / 100
|
||||
+ (tptr->tm_year + 299) / 400);
|
||||
/* bug: this will overflow in the year 2066 AD (with 16 bit int) */
|
||||
/* it will be attributed to Wm the C's millenial celebration */
|
||||
/* and minutes since midnite */
|
||||
*t = tptr->tm_hour * 60 + tptr->tm_min;
|
||||
} /* pretty painless */
|
||||
|
||||
|
||||
static char magic[6];
|
||||
|
||||
void
|
||||
poof(void)
|
||||
{
|
||||
strcpy(magic, DECR('d', 'w', 'a', 'r', 'f'));
|
||||
latency = 45;
|
||||
}
|
||||
|
||||
int
|
||||
Start(void)
|
||||
{
|
||||
int d, t, delay;
|
||||
|
||||
datime(&d, &t);
|
||||
delay = (d - saveday) * 1440 + (t - savet); /* good for about a
|
||||
* month */
|
||||
|
||||
if (delay >= latency) {
|
||||
saved = -1;
|
||||
return (FALSE);
|
||||
}
|
||||
printf("This adventure was suspended a mere %d minute%s ago.",
|
||||
delay, delay == 1 ? "" : "s");
|
||||
if (delay <= latency / 3) {
|
||||
mspeak(2);
|
||||
exit(0);
|
||||
}
|
||||
mspeak(8);
|
||||
if (!wizard()) {
|
||||
mspeak(9);
|
||||
exit(0);
|
||||
}
|
||||
saved = -1;
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/* not as complex as advent/10 (for now) */
|
||||
static int
|
||||
wizard(void)
|
||||
{
|
||||
char *word, *x;
|
||||
if (!yesm(16, 0, 7))
|
||||
return (FALSE);
|
||||
mspeak(17);
|
||||
getin(&word, &x);
|
||||
if (!weq(word, magic)) {
|
||||
mspeak(20);
|
||||
return (FALSE);
|
||||
}
|
||||
mspeak(19);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
ciao(void)
|
||||
{
|
||||
char fname[80];
|
||||
size_t pos;
|
||||
|
||||
printf("What would you like to call the saved version?\n");
|
||||
/* XXX - should use fgetln to avoid arbitrary limit */
|
||||
for (pos = 0; pos < sizeof(fname) - 1; pos++) {
|
||||
int ch;
|
||||
ch = getchar();
|
||||
if (ch == '\n' || ch == EOF)
|
||||
break;
|
||||
fname[pos] = ch;
|
||||
}
|
||||
fname[pos] = '\0';
|
||||
if (save(fname) != 0)
|
||||
return; /* Save failed */
|
||||
printf("To resume, say \"adventure %s\".\n", fname);
|
||||
printf("\"With these rooms I might now have been familiarly ");
|
||||
printf("acquainted.\"\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ran(int range)
|
||||
{
|
||||
long i;
|
||||
|
||||
i = rand() % range;
|
||||
return (i);
|
||||
}
|
|
@ -68,6 +68,9 @@
|
|||
2013/12/1 12:00:00,external/mit/Makefile
|
||||
2013/12/1 12:00:00,external/public-domain
|
||||
2013/12/1 12:00:00,external/README
|
||||
2013/12/1 12:00:00,games/adventure
|
||||
2013/12/1 12:00:00,games/Makefile
|
||||
2013/12/1 12:00:00,games/Makefile.inc
|
||||
2013/12/1 12:00:00,gnu/dist/texinfo
|
||||
2013/12/1 12:00:00,gnu/usr.bin/texinfo
|
||||
2013/12/1 12:00:00,gnu/Makefile
|
||||
|
|
Loading…
Reference in a new issue