Home | History | Annotate | Line # | Download | only in adventure
io.c revision 1.6
      1  1.6     lukem /*	$NetBSD: io.c,v 1.6 1997/10/11 01:53:29 lukem Exp $	*/
      2  1.2       cgd 
      3  1.1       jtc /*-
      4  1.1       jtc  * Copyright (c) 1991, 1993
      5  1.1       jtc  *	The Regents of the University of California.  All rights reserved.
      6  1.1       jtc  *
      7  1.1       jtc  * The game adventure was originally written in Fortran by Will Crowther
      8  1.1       jtc  * and Don Woods.  It was later translated to C and enhanced by Jim
      9  1.1       jtc  * Gillogly.  This code is derived from software contributed to Berkeley
     10  1.1       jtc  * by Jim Gillogly at The Rand Corporation.
     11  1.1       jtc  *
     12  1.1       jtc  * Redistribution and use in source and binary forms, with or without
     13  1.1       jtc  * modification, are permitted provided that the following conditions
     14  1.1       jtc  * are met:
     15  1.1       jtc  * 1. Redistributions of source code must retain the above copyright
     16  1.1       jtc  *    notice, this list of conditions and the following disclaimer.
     17  1.1       jtc  * 2. Redistributions in binary form must reproduce the above copyright
     18  1.1       jtc  *    notice, this list of conditions and the following disclaimer in the
     19  1.1       jtc  *    documentation and/or other materials provided with the distribution.
     20  1.1       jtc  * 3. All advertising materials mentioning features or use of this software
     21  1.1       jtc  *    must display the following acknowledgement:
     22  1.1       jtc  *	This product includes software developed by the University of
     23  1.1       jtc  *	California, Berkeley and its contributors.
     24  1.1       jtc  * 4. Neither the name of the University nor the names of its contributors
     25  1.1       jtc  *    may be used to endorse or promote products derived from this software
     26  1.1       jtc  *    without specific prior written permission.
     27  1.1       jtc  *
     28  1.1       jtc  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     29  1.1       jtc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     30  1.1       jtc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     31  1.1       jtc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     32  1.1       jtc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     33  1.1       jtc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     34  1.1       jtc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     35  1.1       jtc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     36  1.1       jtc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     37  1.1       jtc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     38  1.1       jtc  * SUCH DAMAGE.
     39  1.1       jtc  */
     40  1.1       jtc 
     41  1.4  christos #include <sys/cdefs.h>
     42  1.1       jtc #ifndef lint
     43  1.2       cgd #if 0
     44  1.1       jtc static char sccsid[] = "@(#)io.c	8.1 (Berkeley) 5/31/93";
     45  1.2       cgd #else
     46  1.6     lukem __RCSID("$NetBSD: io.c,v 1.6 1997/10/11 01:53:29 lukem Exp $");
     47  1.2       cgd #endif
     48  1.1       jtc #endif /* not lint */
     49  1.1       jtc 
     50  1.1       jtc /*      Re-coding of advent in C: file i/o and user i/o                 */
     51  1.1       jtc 
     52  1.1       jtc #include <stdio.h>
     53  1.3       cgd #include <string.h>
     54  1.4  christos #include <stdlib.h>
     55  1.4  christos #include "hdr.h"
     56  1.4  christos #include "extern.h"
     57  1.1       jtc 
     58  1.1       jtc 
     59  1.4  christos void
     60  1.6     lukem getin(wrd1, wrd2)		/* get command from user        */
     61  1.6     lukem 	char  **wrd1, **wrd2;	/* no prompt, usually           */
     62  1.6     lukem {
     63  1.6     lukem 	char   *s;
     64  1.6     lukem 	static char wd1buf[MAXSTR], wd2buf[MAXSTR];
     65  1.6     lukem 	int     first, numch;
     66  1.6     lukem 
     67  1.6     lukem 	*wrd1 = wd1buf;				/* return ptr to internal str */
     68  1.6     lukem 	*wrd2 = wd2buf;
     69  1.6     lukem 	wd2buf[0] = 0;				/* in case it isn't set here */
     70  1.6     lukem 	for (s = wd1buf, first = 1, numch = 0;;) {
     71  1.6     lukem 		if ((*s = getchar()) >= 'A' && *s <= 'Z')
     72  1.6     lukem 			*s = *s - ('A' - 'a');
     73  1.6     lukem 		/* convert to upper case */
     74  1.6     lukem 		switch (*s) {			/* start reading from user */
     75  1.6     lukem 		case '\n':
     76  1.6     lukem 			*s = 0;
     77  1.1       jtc 			return;
     78  1.6     lukem 		case ' ':
     79  1.6     lukem 			if (s == wd1buf || s == wd2buf)	/* initial blank */
     80  1.1       jtc 				continue;
     81  1.6     lukem 			*s = 0;
     82  1.6     lukem 			if (first) {		/* finished 1st wd; start 2nd */
     83  1.6     lukem 				first = numch = 0;
     84  1.6     lukem 				s = wd2buf;
     85  1.1       jtc 				break;
     86  1.6     lukem 			} else {		/* finished 2nd word */
     87  1.6     lukem 				FLUSHLINE;
     88  1.6     lukem 				*s = 0;
     89  1.1       jtc 				return;
     90  1.1       jtc 			}
     91  1.6     lukem 		default:
     92  1.6     lukem 			if (++numch >= MAXSTR) {	/* string too long */
     93  1.6     lukem 				printf("Give me a break!!\n");
     94  1.6     lukem 				wd1buf[0] = wd2buf[0] = 0;
     95  1.1       jtc 				FLUSHLINE;
     96  1.1       jtc 				return;
     97  1.1       jtc 			}
     98  1.1       jtc 			s++;
     99  1.1       jtc 		}
    100  1.1       jtc 	}
    101  1.1       jtc }
    102  1.1       jtc 
    103  1.4  christos int
    104  1.6     lukem confirm(mesg)			/* confirm irreversible action  */
    105  1.6     lukem 	char   *mesg;
    106  1.6     lukem {
    107  1.6     lukem 	int     result;
    108  1.6     lukem 	printf("%s", mesg);	/* tell him what he did         */
    109  1.6     lukem 	if (getchar() == 'y')	/* was his first letter a 'y'?  */
    110  1.6     lukem 		result = 1;
    111  1.6     lukem 	else
    112  1.6     lukem 		result = 0;
    113  1.1       jtc 	FLUSHLINE;
    114  1.6     lukem 	return (result);
    115  1.1       jtc }
    116  1.1       jtc 
    117  1.4  christos int
    118  1.6     lukem yes(x, y, z)			/* confirm with rspeak          */
    119  1.6     lukem 	int     x, y, z;
    120  1.6     lukem {
    121  1.6     lukem 	int     result = TRUE;	/* pacify gcc */
    122  1.6     lukem 	char    ch;
    123  1.6     lukem 	for (;;) {
    124  1.6     lukem 		rspeak(x);	/* tell him what we want */
    125  1.6     lukem 		if ((ch = getchar()) == 'y')
    126  1.6     lukem 			result = TRUE;
    127  1.6     lukem 		else
    128  1.6     lukem 			if (ch == 'n')
    129  1.6     lukem 				result = FALSE;
    130  1.1       jtc 		FLUSHLINE;
    131  1.6     lukem 		if (ch == 'y' || ch == 'n')
    132  1.6     lukem 			break;
    133  1.1       jtc 		printf("Please answer the question.\n");
    134  1.1       jtc 	}
    135  1.6     lukem 	if (result == TRUE)
    136  1.6     lukem 		rspeak(y);
    137  1.6     lukem 	if (result == FALSE)
    138  1.6     lukem 		rspeak(z);
    139  1.6     lukem 	return (result);
    140  1.1       jtc }
    141  1.1       jtc 
    142  1.4  christos int
    143  1.6     lukem yesm(x, y, z)			/* confirm with mspeak          */
    144  1.6     lukem 	int     x, y, z;
    145  1.6     lukem {
    146  1.6     lukem 	int     result = TRUE;	/* pacify gcc */
    147  1.6     lukem 	char    ch;
    148  1.6     lukem 	for (;;) {
    149  1.6     lukem 		mspeak(x);	/* tell him what we want */
    150  1.6     lukem 		if ((ch = getchar()) == 'y')
    151  1.6     lukem 			result = TRUE;
    152  1.6     lukem 		else
    153  1.6     lukem 			if (ch == 'n')
    154  1.6     lukem 				result = FALSE;
    155  1.1       jtc 		FLUSHLINE;
    156  1.6     lukem 		if (ch == 'y' || ch == 'n')
    157  1.6     lukem 			break;
    158  1.1       jtc 		printf("Please answer the question.\n");
    159  1.1       jtc 	}
    160  1.6     lukem 	if (result == TRUE)
    161  1.6     lukem 		mspeak(y);
    162  1.6     lukem 	if (result == FALSE)
    163  1.6     lukem 		mspeak(z);
    164  1.6     lukem 	return (result);
    165  1.1       jtc }
    166  1.1       jtc /* FILE *inbuf,*outbuf; */
    167  1.1       jtc 
    168  1.6     lukem char   *inptr;			/* Pointer into virtual disk    */
    169  1.1       jtc 
    170  1.6     lukem int     outsw = 0;		/* putting stuff to data file?  */
    171  1.1       jtc 
    172  1.6     lukem char    iotape[] = "Ax3F'\003tt$8h\315qer*h\017nGKrX\207:!l";
    173  1.6     lukem char   *tape = iotape;		/* pointer to encryption tape   */
    174  1.1       jtc 
    175  1.4  christos int
    176  1.6     lukem next()
    177  1.6     lukem {				/* next virtual char, bump adr  */
    178  1.6     lukem 	int     ch;
    179  1.6     lukem 
    180  1.6     lukem 	ch = (*inptr ^ random()) & 0xFF;	/* Decrypt input data           */
    181  1.6     lukem 	if (outsw) {		/* putting data in tmp file     */
    182  1.6     lukem 		if (*tape == 0)
    183  1.6     lukem 			tape = iotape;	/* rewind encryption tape       */
    184  1.6     lukem 		*inptr = ch ^ *tape++;	/* re-encrypt and replace value */
    185  1.1       jtc 	}
    186  1.1       jtc 	inptr++;
    187  1.6     lukem 	return (ch);
    188  1.1       jtc }
    189  1.1       jtc 
    190  1.6     lukem char    breakch;		/* tell which char ended rnum   */
    191  1.1       jtc 
    192  1.4  christos void
    193  1.6     lukem rdata()
    194  1.6     lukem {				/* "read" data from virtual file */
    195  1.6     lukem 	int     sect;
    196  1.6     lukem 	char    ch;
    197  1.1       jtc 
    198  1.6     lukem 	inptr = data_file;	/* Pointer to virtual data file */
    199  1.6     lukem 	srandom(SEED);		/* which is lightly encrypted.  */
    200  1.1       jtc 
    201  1.6     lukem 	clsses = 1;
    202  1.6     lukem 	for (;;) {		/* read data sections           */
    203  1.6     lukem 		sect = next() - '0';	/* 1st digit of section number  */
    204  1.1       jtc #ifdef VERBOSE
    205  1.6     lukem 		printf("Section %c", sect + '0');
    206  1.1       jtc #endif
    207  1.6     lukem 		if ((ch = next()) != LF) {	/* is there a second digit?     */
    208  1.1       jtc 			FLUSHLF;
    209  1.1       jtc #ifdef VERBOSE
    210  1.1       jtc 			putchar(ch);
    211  1.1       jtc #endif
    212  1.6     lukem 			sect = 10 * sect + ch - '0';
    213  1.1       jtc 		}
    214  1.1       jtc #ifdef VERBOSE
    215  1.1       jtc 		putchar('\n');
    216  1.1       jtc #endif
    217  1.6     lukem 		switch (sect) {
    218  1.6     lukem 		case 0:	/* finished reading database    */
    219  1.1       jtc 			return;
    220  1.6     lukem 		case 1:	/* long form descriptions       */
    221  1.1       jtc 			rdesc(1);
    222  1.1       jtc 			break;
    223  1.6     lukem 		case 2:	/* short form descriptions      */
    224  1.1       jtc 			rdesc(2);
    225  1.1       jtc 			break;
    226  1.6     lukem 		case 3:	/* travel table                 */
    227  1.6     lukem 			rtrav();
    228  1.6     lukem 			break;
    229  1.6     lukem 		case 4:	/* vocabulary                   */
    230  1.1       jtc 			rvoc();
    231  1.1       jtc 			break;
    232  1.6     lukem 		case 5:	/* object descriptions          */
    233  1.1       jtc 			rdesc(5);
    234  1.1       jtc 			break;
    235  1.6     lukem 		case 6:	/* arbitrary messages           */
    236  1.1       jtc 			rdesc(6);
    237  1.1       jtc 			break;
    238  1.6     lukem 		case 7:	/* object locations             */
    239  1.6     lukem 			rlocs();
    240  1.6     lukem 			break;
    241  1.6     lukem 		case 8:	/* action defaults              */
    242  1.6     lukem 			rdflt();
    243  1.6     lukem 			break;
    244  1.6     lukem 		case 9:	/* liquid assets                */
    245  1.6     lukem 			rliq();
    246  1.6     lukem 			break;
    247  1.6     lukem 		case 10:	/* class messages               */
    248  1.1       jtc 			rdesc(10);
    249  1.1       jtc 			break;
    250  1.6     lukem 		case 11:	/* hints                        */
    251  1.6     lukem 			rhints();
    252  1.6     lukem 			break;
    253  1.6     lukem 		case 12:	/* magic messages               */
    254  1.1       jtc 			rdesc(12);
    255  1.1       jtc 			break;
    256  1.6     lukem 		default:
    257  1.6     lukem 			printf("Invalid data section number: %d\n", sect);
    258  1.6     lukem 			for (;;)
    259  1.6     lukem 				putchar(next());
    260  1.1       jtc 		}
    261  1.6     lukem 		if (breakch != LF)	/* routines return after "-1"   */
    262  1.1       jtc 			FLUSHLF;
    263  1.1       jtc 	}
    264  1.1       jtc }
    265  1.1       jtc 
    266  1.6     lukem char    nbf[12];
    267  1.1       jtc 
    268  1.1       jtc 
    269  1.4  christos int
    270  1.6     lukem rnum()
    271  1.6     lukem {				/* read initial location num    */
    272  1.6     lukem 	char   *s;
    273  1.6     lukem 	tape = iotape;		/* restart encryption tape      */
    274  1.6     lukem 	for (s = nbf, *s = 0;; s++)
    275  1.6     lukem 		if ((*s = next()) == TAB || *s == '\n' || *s == LF)
    276  1.6     lukem 			break;
    277  1.6     lukem 	breakch = *s;		/* save char for rtrav()        */
    278  1.6     lukem 	*s = 0;			/* got the number as ascii      */
    279  1.6     lukem 	if (nbf[0] == '-')
    280  1.6     lukem 		return (-1);	/* end of data                  */
    281  1.6     lukem 	return (atoi(nbf));	/* convert it to integer        */
    282  1.6     lukem }
    283  1.6     lukem 
    284  1.6     lukem char   *seekhere;
    285  1.6     lukem 
    286  1.6     lukem void
    287  1.6     lukem rdesc(sect)			/* read description-format msgs */
    288  1.6     lukem 	int     sect;
    289  1.6     lukem {
    290  1.6     lukem 	int     locc;
    291  1.6     lukem 	char   *seekstart, *maystart;
    292  1.6     lukem 
    293  1.6     lukem 	seekhere = inptr;	/* Where are we in virtual file? */
    294  1.6     lukem 	outsw = 1;		/* these msgs go into tmp file  */
    295  1.6     lukem 	for (oldloc = -1, seekstart = seekhere;;) {
    296  1.6     lukem 		maystart = inptr;	/* maybe starting new entry     */
    297  1.6     lukem 		if ((locc = rnum()) != oldloc && oldloc >= 0	/* finished msg */
    298  1.6     lukem 		    && !(sect == 5 && (locc == 0 || locc >= 100))) {	/* unless sect 5 */
    299  1.6     lukem 			switch (sect) {	/* now put it into right table  */
    300  1.6     lukem 			case 1:/* long descriptions            */
    301  1.6     lukem 				ltext[oldloc].seekadr = seekhere;
    302  1.6     lukem 				ltext[oldloc].txtlen = maystart - seekstart;
    303  1.1       jtc 				break;
    304  1.6     lukem 			case 2:/* short descriptions           */
    305  1.6     lukem 				stext[oldloc].seekadr = seekhere;
    306  1.6     lukem 				stext[oldloc].txtlen = maystart - seekstart;
    307  1.1       jtc 				break;
    308  1.6     lukem 			case 5:/* object descriptions          */
    309  1.6     lukem 				ptext[oldloc].seekadr = seekhere;
    310  1.6     lukem 				ptext[oldloc].txtlen = maystart - seekstart;
    311  1.1       jtc 				break;
    312  1.6     lukem 			case 6:/* random messages              */
    313  1.6     lukem 				if (oldloc > RTXSIZ) {
    314  1.6     lukem 					printf("Too many random msgs\n");
    315  1.1       jtc 					exit(0);
    316  1.1       jtc 				}
    317  1.6     lukem 				rtext[oldloc].seekadr = seekhere;
    318  1.6     lukem 				rtext[oldloc].txtlen = maystart - seekstart;
    319  1.1       jtc 				break;
    320  1.6     lukem 			case 10:	/* class messages               */
    321  1.6     lukem 				ctext[clsses].seekadr = seekhere;
    322  1.6     lukem 				ctext[clsses].txtlen = maystart - seekstart;
    323  1.6     lukem 				cval[clsses++] = oldloc;
    324  1.1       jtc 				break;
    325  1.6     lukem 			case 12:	/* magic messages               */
    326  1.6     lukem 				if (oldloc > MAGSIZ) {
    327  1.6     lukem 					printf("Too many magic msgs\n");
    328  1.1       jtc 					exit(0);
    329  1.1       jtc 				}
    330  1.6     lukem 				mtext[oldloc].seekadr = seekhere;
    331  1.6     lukem 				mtext[oldloc].txtlen = maystart - seekstart;
    332  1.1       jtc 				break;
    333  1.6     lukem 			default:
    334  1.1       jtc 				printf("rdesc called with bad section\n");
    335  1.1       jtc 				exit(0);
    336  1.1       jtc 			}
    337  1.6     lukem 			seekhere += maystart - seekstart;
    338  1.1       jtc 		}
    339  1.6     lukem 		if (locc < 0) {
    340  1.6     lukem 			outsw = 0;	/* turn off output              */
    341  1.6     lukem 			seekhere += 3;	/* -1<delimiter>                */
    342  1.1       jtc 			return;
    343  1.1       jtc 		}
    344  1.6     lukem 		if (sect != 5 || (locc > 0 && locc < 100)) {
    345  1.6     lukem 			if (oldloc != locc)	/* starting a new message       */
    346  1.6     lukem 				seekstart = maystart;
    347  1.6     lukem 			oldloc = locc;
    348  1.1       jtc 		}
    349  1.6     lukem 		FLUSHLF;	/* scan the line                */
    350  1.1       jtc 	}
    351  1.1       jtc }
    352  1.1       jtc 
    353  1.4  christos void
    354  1.6     lukem rtrav()
    355  1.6     lukem {				/* read travel table            */
    356  1.6     lukem 	int     locc;
    357  1.5     lukem 	struct travlist *t = NULL;
    358  1.6     lukem 	char   *s;
    359  1.6     lukem 	char    buf[12];
    360  1.6     lukem 	int     len, m, n, entries = 0;
    361  1.6     lukem 
    362  1.6     lukem 	for (oldloc = -1;;) {	/* get another line             */
    363  1.6     lukem 		if ((locc = rnum()) != oldloc && oldloc >= 0) {	/* end of entry */
    364  1.6     lukem 			t->next = 0;	/* terminate the old entry      */
    365  1.6     lukem 			/* printf("%d:%d entries\n",oldloc,entries);       */
    366  1.6     lukem 			/* twrite(oldloc);                                 */
    367  1.6     lukem 		}
    368  1.6     lukem 		if (locc == -1)
    369  1.6     lukem 			return;
    370  1.6     lukem 		if (locc != oldloc) {	/* getting a new entry         */
    371  1.6     lukem 			t = travel[locc] = (struct travlist *) malloc(sizeof(struct travlist));
    372  1.6     lukem 			/* printf("New travel list for %d\n",locc);        */
    373  1.6     lukem 			entries = 0;
    374  1.6     lukem 			oldloc = locc;
    375  1.6     lukem 		}
    376  1.6     lukem 		for (s = buf;; s++)	/* get the newloc number /ASCII */
    377  1.6     lukem 			if ((*s = next()) == TAB || *s == LF)
    378  1.6     lukem 				break;
    379  1.6     lukem 		*s = 0;
    380  1.6     lukem 		len = length(buf) - 1;	/* quad long number handling    */
    381  1.6     lukem 		/* printf("Newloc: %s (%d chars)\n",buf,len);              */
    382  1.6     lukem 		if (len < 4) {	/* no "m" conditions            */
    383  1.6     lukem 			m = 0;
    384  1.6     lukem 			n = atoi(buf);	/* newloc mod 1000 = newloc     */
    385  1.6     lukem 		} else {	/* a long integer               */
    386  1.6     lukem 			n = atoi(buf + len - 3);
    387  1.6     lukem 			buf[len - 3] = 0;	/* terminate newloc/1000        */
    388  1.6     lukem 			m = atoi(buf);
    389  1.6     lukem 		}
    390  1.6     lukem 		while (breakch != LF) {	/* only do one line at a time   */
    391  1.6     lukem 			if (entries++)
    392  1.6     lukem 				t = t->next = (struct travlist *) malloc(sizeof(struct travlist));
    393  1.6     lukem 			t->tverb = rnum();	/* get verb from the file       */
    394  1.6     lukem 			t->tloc = n;	/* table entry mod 1000         */
    395  1.6     lukem 			t->conditions = m;	/* table entry / 1000           */
    396  1.6     lukem 			/* printf("entry %d for %d\n",entries,locc);       */
    397  1.1       jtc 		}
    398  1.1       jtc 	}
    399  1.1       jtc }
    400  1.1       jtc #ifdef DEBUG
    401  1.1       jtc 
    402  1.4  christos void
    403  1.6     lukem twrite(loq)			/* travel options from this loc */
    404  1.6     lukem 	int     loq;
    405  1.6     lukem {
    406  1.6     lukem 	struct travlist *t;
    407  1.1       jtc 	printf("If");
    408  1.1       jtc 	speak(&ltext[loq]);
    409  1.1       jtc 	printf("then\n");
    410  1.6     lukem 	for (t = travel[loq]; t != 0; t = t->next) {
    411  1.6     lukem 		printf("verb %d takes you to ", t->tverb);
    412  1.6     lukem 		if (t->tloc <= 300)
    413  1.1       jtc 			speak(&ltext[t->tloc]);
    414  1.1       jtc 		else
    415  1.6     lukem 			if (t->tloc <= 500)
    416  1.6     lukem 				printf("special code %d\n", t->tloc - 300);
    417  1.6     lukem 			else
    418  1.6     lukem 				rspeak(t->tloc - 500);
    419  1.6     lukem 		printf("under conditions %d\n", t->conditions);
    420  1.1       jtc 	}
    421  1.1       jtc }
    422  1.6     lukem #endif				/* DEBUG */
    423  1.1       jtc 
    424  1.4  christos void
    425  1.1       jtc rvoc()
    426  1.6     lukem {
    427  1.6     lukem 	char   *s;		/* read the vocabulary          */
    428  1.6     lukem 	int     index;
    429  1.6     lukem 	char    buf[6];
    430  1.6     lukem 	for (;;) {
    431  1.6     lukem 		index = rnum();
    432  1.6     lukem 		if (index < 0)
    433  1.6     lukem 			break;
    434  1.6     lukem 		for (s = buf, *s = 0;; s++)	/* get the word                 */
    435  1.6     lukem 			if ((*s = next()) == TAB || *s == '\n' || *s == LF
    436  1.6     lukem 			    || *s == ' ')
    437  1.6     lukem 				break;
    438  1.6     lukem 		/* terminate word with newline, LF, tab, blank  */
    439  1.6     lukem 		if (*s != '\n' && *s != LF)
    440  1.6     lukem 			FLUSHLF;/* can be comments    */
    441  1.6     lukem 		*s = 0;
    442  1.6     lukem 		/* printf("\"%s\"=%d\n",buf,index); */
    443  1.6     lukem 		vocab(buf, -2, index);
    444  1.1       jtc 	}
    445  1.1       jtc /*	prht();	*/
    446  1.1       jtc }
    447  1.1       jtc 
    448  1.1       jtc 
    449  1.4  christos void
    450  1.6     lukem rlocs()
    451  1.6     lukem {				/* initial object locations     */
    452  1.6     lukem 	for (;;) {
    453  1.6     lukem 		if ((obj = rnum()) < 0)
    454  1.6     lukem 			break;
    455  1.6     lukem 		plac[obj] = rnum();	/* initial loc for this obj     */
    456  1.6     lukem 		if (breakch == TAB)	/* there's another entry        */
    457  1.6     lukem 			fixd[obj] = rnum();
    458  1.6     lukem 		else
    459  1.6     lukem 			fixd[obj] = 0;
    460  1.1       jtc 	}
    461  1.1       jtc }
    462  1.1       jtc 
    463  1.4  christos void
    464  1.6     lukem rdflt()
    465  1.6     lukem {				/* default verb messages        */
    466  1.6     lukem 	for (;;) {
    467  1.6     lukem 		if ((verb = rnum()) < 0)
    468  1.6     lukem 			break;
    469  1.6     lukem 		actspk[verb] = rnum();
    470  1.1       jtc 	}
    471  1.1       jtc }
    472  1.1       jtc 
    473  1.4  christos void
    474  1.6     lukem rliq()
    475  1.6     lukem {				/* liquid assets &c: cond bits  */
    476  1.6     lukem 	int     bitnum;
    477  1.6     lukem 	for (;;) {		/* read new bit list            */
    478  1.6     lukem 		if ((bitnum = rnum()) < 0)
    479  1.6     lukem 			break;
    480  1.6     lukem 		for (;;) {	/* read locs for bits           */
    481  1.6     lukem 			cond[rnum()] |= setbit[bitnum];
    482  1.6     lukem 			if (breakch == LF)
    483  1.6     lukem 				break;
    484  1.1       jtc 		}
    485  1.1       jtc 	}
    486  1.1       jtc }
    487  1.1       jtc 
    488  1.4  christos void
    489  1.1       jtc rhints()
    490  1.6     lukem {
    491  1.6     lukem 	int     hintnum, i;
    492  1.6     lukem 	hntmax = 0;
    493  1.6     lukem 	for (;;) {
    494  1.6     lukem 		if ((hintnum = rnum()) < 0)
    495  1.6     lukem 			break;
    496  1.6     lukem 		for (i = 1; i < 5; i++)
    497  1.6     lukem 			hints[hintnum][i] = rnum();
    498  1.6     lukem 		if (hintnum > hntmax)
    499  1.6     lukem 			hntmax = hintnum;
    500  1.1       jtc 	}
    501  1.1       jtc }
    502  1.1       jtc 
    503  1.1       jtc 
    504  1.4  christos void
    505  1.1       jtc rspeak(msg)
    506  1.6     lukem 	int     msg;
    507  1.6     lukem {
    508  1.6     lukem 	if (msg != 0)
    509  1.6     lukem 		speak(&rtext[msg]);
    510  1.1       jtc }
    511  1.1       jtc 
    512  1.1       jtc 
    513  1.4  christos void
    514  1.1       jtc mspeak(msg)
    515  1.6     lukem 	int     msg;
    516  1.6     lukem {
    517  1.6     lukem 	if (msg != 0)
    518  1.6     lukem 		speak(&mtext[msg]);
    519  1.1       jtc }
    520  1.1       jtc 
    521  1.1       jtc 
    522  1.4  christos void
    523  1.6     lukem speak(msg)			/* read, decrypt, and print a message (not
    524  1.6     lukem 				 * ptext)      */
    525  1.6     lukem 	struct text *msg;	/* msg is a pointer to seek address and length
    526  1.6     lukem 				 * of mess */
    527  1.1       jtc {
    528  1.6     lukem 	char   *s, nonfirst;
    529  1.1       jtc 
    530  1.1       jtc 	s = msg->seekadr;
    531  1.6     lukem 	nonfirst = 0;
    532  1.6     lukem 	while (s - msg->seekadr < msg->txtlen) {	/* read a line at a time */
    533  1.6     lukem 		tape = iotape;	/* restart decryption tape      */
    534  1.6     lukem 		while ((*s++ ^ *tape++) != TAB);	/* read past loc num       */
    535  1.1       jtc 		/* assume tape is longer than location number           */
    536  1.6     lukem 		/* plus the lookahead put together                    */
    537  1.1       jtc 		if ((*s ^ *tape) == '>' &&
    538  1.6     lukem 		    (*(s + 1) ^ *(tape + 1)) == '$' &&
    539  1.6     lukem 		    (*(s + 2) ^ *(tape + 2)) == '<')
    540  1.6     lukem 			break;
    541  1.6     lukem 		if (blklin && !nonfirst++)
    542  1.6     lukem 			putchar('\n');
    543  1.6     lukem 		do {
    544  1.6     lukem 			if (*tape == 0)
    545  1.6     lukem 				tape = iotape;	/* rewind decryp tape */
    546  1.1       jtc 			putchar(*s ^ *tape);
    547  1.6     lukem 		} while ((*s++ ^ *tape++) != LF);	/* better end with LF   */
    548  1.1       jtc 	}
    549  1.1       jtc }
    550  1.1       jtc 
    551  1.1       jtc 
    552  1.4  christos void
    553  1.6     lukem pspeak(m, skip)			/* read, decrypt an print a ptext message              */
    554  1.6     lukem 	int     m;		/* msg is the number of all the p msgs for
    555  1.6     lukem 				 * this place  */
    556  1.6     lukem 	int     skip;		/* assumes object 1 doesn't have prop 1, obj 2
    557  1.6     lukem 				 * no prop 2 &c */
    558  1.1       jtc {
    559  1.6     lukem 	char   *s, nonfirst;
    560  1.6     lukem 	char   *numst, save;
    561  1.1       jtc 	struct text *msg;
    562  1.6     lukem 	char   *tbuf;
    563  1.1       jtc 
    564  1.1       jtc 	msg = &ptext[m];
    565  1.6     lukem 	if ((tbuf = (char *) malloc(msg->txtlen + 1)) == 0)
    566  1.6     lukem 		bug(108);
    567  1.6     lukem 	memcpy(tbuf, msg->seekadr, msg->txtlen + 1);	/* Room to null */
    568  1.1       jtc 	s = tbuf;
    569  1.1       jtc 
    570  1.6     lukem 	nonfirst = 0;
    571  1.6     lukem 	while (s - tbuf < msg->txtlen) {	/* read line at a time */
    572  1.6     lukem 		tape = iotape;	/* restart decryption tape      */
    573  1.6     lukem 		for (numst = s; (*s ^= *tape++) != TAB; s++);	/* get number  */
    574  1.6     lukem 
    575  1.6     lukem 		save = *s;	/* Temporarily trash the string (cringe) */
    576  1.6     lukem 		*s++ = 0;	/* decrypting number within the string          */
    577  1.6     lukem 
    578  1.6     lukem 		if (atoi(numst) != 100 * skip && skip >= 0) {
    579  1.6     lukem 			while ((*s++ ^ *tape++) != LF)	/* flush the line    */
    580  1.6     lukem 				if (*tape == 0)
    581  1.6     lukem 					tape = iotape;
    582  1.1       jtc 			continue;
    583  1.1       jtc 		}
    584  1.6     lukem 		if ((*s ^ *tape) == '>' && (*(s + 1) ^ *(tape + 1)) == '$' &&
    585  1.6     lukem 		    (*(s + 2) ^ *(tape + 2)) == '<')
    586  1.6     lukem 			break;
    587  1.6     lukem 		if (blklin && !nonfirst++)
    588  1.6     lukem 			putchar('\n');
    589  1.6     lukem 		do {
    590  1.6     lukem 			if (*tape == 0)
    591  1.6     lukem 				tape = iotape;
    592  1.6     lukem 			putchar(*s ^ *tape);
    593  1.6     lukem 		} while ((*s++ ^ *tape++) != LF);	/* better end with LF   */
    594  1.6     lukem 		if (skip < 0)
    595  1.6     lukem 			break;
    596  1.1       jtc 	}
    597  1.1       jtc 	free(tbuf);
    598  1.1       jtc }
    599