Home | History | Annotate | Line # | Download | only in adventure
io.c revision 1.2
      1  1.2  cgd /*	$NetBSD: io.c,v 1.2 1995/03/21 12:05:05 cgd 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.1  jtc #ifndef lint
     42  1.2  cgd #if 0
     43  1.1  jtc static char sccsid[] = "@(#)io.c	8.1 (Berkeley) 5/31/93";
     44  1.2  cgd #else
     45  1.2  cgd static char rcsid[] = "$NetBSD: io.c,v 1.2 1995/03/21 12:05:05 cgd Exp $";
     46  1.2  cgd #endif
     47  1.1  jtc #endif /* not lint */
     48  1.1  jtc 
     49  1.1  jtc /*      Re-coding of advent in C: file i/o and user i/o                 */
     50  1.1  jtc 
     51  1.1  jtc #include "hdr.h"
     52  1.1  jtc #include <stdio.h>
     53  1.1  jtc 
     54  1.1  jtc 
     55  1.1  jtc getin(wrd1,wrd2)                        /* get command from user        */
     56  1.1  jtc char **wrd1,**wrd2;                     /* no prompt, usually           */
     57  1.1  jtc {       register char *s;
     58  1.1  jtc 	static char wd1buf[MAXSTR],wd2buf[MAXSTR];
     59  1.1  jtc 	int first, numch;
     60  1.1  jtc 
     61  1.1  jtc 	*wrd1=wd1buf;                   /* return ptr to internal string*/
     62  1.1  jtc 	*wrd2=wd2buf;
     63  1.1  jtc 	wd2buf[0]=0;                    /* in case it isn't set here    */
     64  1.1  jtc 	for (s=wd1buf, first=1, numch=0;;)
     65  1.1  jtc 	{       if ((*s=getchar())>='A' && *s <='Z') *s = *s - ('A' -'a');
     66  1.1  jtc 					/* convert to upper case        */
     67  1.1  jtc 		switch(*s)              /* start reading from user      */
     68  1.1  jtc 		{   case '\n':
     69  1.1  jtc 			*s=0;
     70  1.1  jtc 			return;
     71  1.1  jtc 		    case ' ':
     72  1.1  jtc 			if (s==wd1buf||s==wd2buf)  /* initial blank   */
     73  1.1  jtc 				continue;
     74  1.1  jtc 			*s=0;
     75  1.1  jtc 			if (first)      /* finished 1st wd; start 2nd   */
     76  1.1  jtc 			{       first=numch=0;
     77  1.1  jtc 				s=wd2buf;
     78  1.1  jtc 				break;
     79  1.1  jtc 			}
     80  1.1  jtc 			else            /* finished 2nd word            */
     81  1.1  jtc 			{       FLUSHLINE;
     82  1.1  jtc 				*s=0;
     83  1.1  jtc 				return;
     84  1.1  jtc 			}
     85  1.1  jtc 		    default:
     86  1.1  jtc 			if (++numch>=MAXSTR)    /* string too long      */
     87  1.1  jtc 			{       printf("Give me a break!!\n");
     88  1.1  jtc 				wd1buf[0]=wd2buf[0]=0;
     89  1.1  jtc 				FLUSHLINE;
     90  1.1  jtc 				return;
     91  1.1  jtc 			}
     92  1.1  jtc 			s++;
     93  1.1  jtc 		}
     94  1.1  jtc 	}
     95  1.1  jtc }
     96  1.1  jtc 
     97  1.1  jtc 
     98  1.1  jtc confirm(mesg)                           /* confirm irreversible action  */
     99  1.1  jtc char *mesg;
    100  1.1  jtc {       register int result;
    101  1.1  jtc 	printf("%s",mesg);              /* tell him what he did         */
    102  1.1  jtc 	if (getchar()=='y')             /* was his first letter a 'y'?  */
    103  1.1  jtc 		result=1;
    104  1.1  jtc 	else    result=0;
    105  1.1  jtc 	FLUSHLINE;
    106  1.1  jtc 	return(result);
    107  1.1  jtc }
    108  1.1  jtc 
    109  1.1  jtc yes(x,y,z)                              /* confirm with rspeak          */
    110  1.1  jtc int x,y,z;
    111  1.1  jtc {       register int result;
    112  1.1  jtc 	register char ch;
    113  1.1  jtc 	for (;;)
    114  1.1  jtc 	{       rspeak(x);                     /* tell him what we want*/
    115  1.1  jtc 		if ((ch=getchar())=='y')
    116  1.1  jtc 			result=TRUE;
    117  1.1  jtc 		else if (ch=='n') result=FALSE;
    118  1.1  jtc 		FLUSHLINE;
    119  1.1  jtc 		if (ch=='y'|| ch=='n') break;
    120  1.1  jtc 		printf("Please answer the question.\n");
    121  1.1  jtc 	}
    122  1.1  jtc 	if (result==TRUE) rspeak(y);
    123  1.1  jtc 	if (result==FALSE) rspeak(z);
    124  1.1  jtc 	return(result);
    125  1.1  jtc }
    126  1.1  jtc 
    127  1.1  jtc yesm(x,y,z)                             /* confirm with mspeak          */
    128  1.1  jtc int x,y,z;
    129  1.1  jtc {       register int result;
    130  1.1  jtc 	register char ch;
    131  1.1  jtc 	for (;;)
    132  1.1  jtc 	{       mspeak(x);                     /* tell him what we want*/
    133  1.1  jtc 		if ((ch=getchar())=='y')
    134  1.1  jtc 			result=TRUE;
    135  1.1  jtc 		else if (ch=='n') result=FALSE;
    136  1.1  jtc 		FLUSHLINE;
    137  1.1  jtc 		if (ch=='y'|| ch=='n') break;
    138  1.1  jtc 		printf("Please answer the question.\n");
    139  1.1  jtc 	}
    140  1.1  jtc 	if (result==TRUE) mspeak(y);
    141  1.1  jtc 	if (result==FALSE) mspeak(z);
    142  1.1  jtc 	return(result);
    143  1.1  jtc }
    144  1.1  jtc 
    145  1.1  jtc /* FILE *inbuf,*outbuf; */
    146  1.1  jtc 
    147  1.1  jtc char *inptr;                            /* Pointer into virtual disk    */
    148  1.1  jtc 
    149  1.1  jtc int outsw = 0;				/* putting stuff to data file?  */
    150  1.1  jtc 
    151  1.1  jtc char iotape[] = "Ax3F'\003tt$8h\315qer*h\017nGKrX\207:!l";
    152  1.1  jtc char *tape = iotape;			/* pointer to encryption tape   */
    153  1.1  jtc 
    154  1.1  jtc next()                                  /* next virtual char, bump adr  */
    155  1.1  jtc {
    156  1.1  jtc 	int ch;
    157  1.1  jtc 
    158  1.1  jtc 	ch=(*inptr ^ random()) & 0xFF;  /* Decrypt input data           */
    159  1.1  jtc 	if (outsw)                      /* putting data in tmp file     */
    160  1.1  jtc 	{   if (*tape==0) tape=iotape;  /* rewind encryption tape       */
    161  1.1  jtc 	    *inptr = ch ^ *tape++;      /* re-encrypt and replace value */
    162  1.1  jtc 	}
    163  1.1  jtc 	inptr++;
    164  1.1  jtc 	return(ch);
    165  1.1  jtc }
    166  1.1  jtc 
    167  1.1  jtc char breakch;                           /* tell which char ended rnum   */
    168  1.1  jtc 
    169  1.1  jtc rdata()                                 /* "read" data from virtual file*/
    170  1.1  jtc {       register int sect;
    171  1.1  jtc 	register char ch;
    172  1.1  jtc 
    173  1.1  jtc 	inptr = data_file;              /* Pointer to virtual data file */
    174  1.1  jtc 	srandom(SEED);                  /* which is lightly encrypted.  */
    175  1.1  jtc 
    176  1.1  jtc 	clsses=1;
    177  1.1  jtc 	for (;;)                        /* read data sections           */
    178  1.1  jtc 	{       sect=next()-'0';        /* 1st digit of section number  */
    179  1.1  jtc #ifdef VERBOSE
    180  1.1  jtc 		printf("Section %c",sect+'0');
    181  1.1  jtc #endif
    182  1.1  jtc 		if ((ch=next())!=LF)    /* is there a second digit?     */
    183  1.1  jtc 		{
    184  1.1  jtc 			FLUSHLF;
    185  1.1  jtc #ifdef VERBOSE
    186  1.1  jtc 			putchar(ch);
    187  1.1  jtc #endif
    188  1.1  jtc 			sect=10*sect+ch-'0';
    189  1.1  jtc 		}
    190  1.1  jtc #ifdef VERBOSE
    191  1.1  jtc 		putchar('\n');
    192  1.1  jtc #endif
    193  1.1  jtc 		switch(sect)
    194  1.1  jtc 		{   case 0:             /* finished reading database    */
    195  1.1  jtc 			return;
    196  1.1  jtc 		    case 1:             /* long form descriptions       */
    197  1.1  jtc 			rdesc(1);
    198  1.1  jtc 			break;
    199  1.1  jtc 		    case 2:             /* short form descriptions      */
    200  1.1  jtc 			rdesc(2);
    201  1.1  jtc 			break;
    202  1.1  jtc 		    case 3:             /* travel table                 */
    203  1.1  jtc 			rtrav();   break;
    204  1.1  jtc 		    case 4:             /* vocabulary                   */
    205  1.1  jtc 			rvoc();
    206  1.1  jtc 			break;
    207  1.1  jtc 		    case 5:             /* object descriptions          */
    208  1.1  jtc 			rdesc(5);
    209  1.1  jtc 			break;
    210  1.1  jtc 		    case 6:             /* arbitrary messages           */
    211  1.1  jtc 			rdesc(6);
    212  1.1  jtc 			break;
    213  1.1  jtc 		    case 7:             /* object locations             */
    214  1.1  jtc 			rlocs();   break;
    215  1.1  jtc 		    case 8:             /* action defaults              */
    216  1.1  jtc 			rdflt();   break;
    217  1.1  jtc 		    case 9:             /* liquid assets                */
    218  1.1  jtc 			rliq();    break;
    219  1.1  jtc 		    case 10:            /* class messages               */
    220  1.1  jtc 			rdesc(10);
    221  1.1  jtc 			break;
    222  1.1  jtc 		    case 11:            /* hints                        */
    223  1.1  jtc 			rhints();  break;
    224  1.1  jtc 		    case 12:            /* magic messages               */
    225  1.1  jtc 			rdesc(12);
    226  1.1  jtc 			break;
    227  1.1  jtc 		    default:
    228  1.1  jtc 			printf("Invalid data section number: %d\n",sect);
    229  1.1  jtc 			for (;;) putchar(next());
    230  1.1  jtc 		}
    231  1.1  jtc 		if (breakch!=LF)        /* routines return after "-1"   */
    232  1.1  jtc 			FLUSHLF;
    233  1.1  jtc 	}
    234  1.1  jtc }
    235  1.1  jtc 
    236  1.1  jtc char nbf[12];
    237  1.1  jtc 
    238  1.1  jtc 
    239  1.1  jtc rnum()                                  /* read initial location num    */
    240  1.1  jtc {       register char *s;
    241  1.1  jtc 	tape = iotape;                  /* restart encryption tape      */
    242  1.1  jtc 	for (s=nbf,*s=0;; s++)
    243  1.1  jtc 		if ((*s=next())==TAB || *s=='\n' || *s==LF)
    244  1.1  jtc 			break;
    245  1.1  jtc 	breakch= *s;                    /* save char for rtrav()        */
    246  1.1  jtc 	*s=0;                           /* got the number as ascii      */
    247  1.1  jtc 	if (nbf[0]=='-') return(-1);    /* end of data                  */
    248  1.1  jtc 	return(atoi(nbf));              /* convert it to integer        */
    249  1.1  jtc }
    250  1.1  jtc 
    251  1.1  jtc char *seekhere;
    252  1.1  jtc 
    253  1.1  jtc rdesc(sect)                             /* read description-format msgs */
    254  1.1  jtc int sect;
    255  1.1  jtc {       register char *s,*t;
    256  1.1  jtc 	register int locc;
    257  1.1  jtc 	char *seekstart, *maystart, *adrstart;
    258  1.1  jtc 	char *entry;
    259  1.1  jtc 
    260  1.1  jtc 	seekhere = inptr;               /* Where are we in virtual file?*/
    261  1.1  jtc 	outsw=1;                        /* these msgs go into tmp file  */
    262  1.1  jtc 	for (oldloc= -1, seekstart=seekhere;;)
    263  1.1  jtc 	{       maystart=inptr;         /* maybe starting new entry     */
    264  1.1  jtc 		if ((locc=rnum())!=oldloc && oldloc>=0  /* finished msg */
    265  1.1  jtc 		    && ! (sect==5 && (locc==0 || locc>=100)))/* unless sect 5*/
    266  1.1  jtc 		{       switch(sect)    /* now put it into right table  */
    267  1.1  jtc 			{   case 1:     /* long descriptions            */
    268  1.1  jtc 				ltext[oldloc].seekadr=seekhere;
    269  1.1  jtc 				ltext[oldloc].txtlen=maystart-seekstart;
    270  1.1  jtc 				break;
    271  1.1  jtc 			    case 2:     /* short descriptions           */
    272  1.1  jtc 				stext[oldloc].seekadr=seekhere;
    273  1.1  jtc 				stext[oldloc].txtlen=maystart-seekstart;
    274  1.1  jtc 				break;
    275  1.1  jtc 			    case 5:     /* object descriptions          */
    276  1.1  jtc 				ptext[oldloc].seekadr=seekhere;
    277  1.1  jtc 				ptext[oldloc].txtlen=maystart-seekstart;
    278  1.1  jtc 				break;
    279  1.1  jtc 			    case 6:     /* random messages              */
    280  1.1  jtc 				if (oldloc>RTXSIZ)
    281  1.1  jtc 				{       printf("Too many random msgs\n");
    282  1.1  jtc 					exit(0);
    283  1.1  jtc 				}
    284  1.1  jtc 				rtext[oldloc].seekadr=seekhere;
    285  1.1  jtc 				rtext[oldloc].txtlen=maystart-seekstart;
    286  1.1  jtc 				break;
    287  1.1  jtc 			    case 10:    /* class messages               */
    288  1.1  jtc 				ctext[clsses].seekadr=seekhere;
    289  1.1  jtc 				ctext[clsses].txtlen=maystart-seekstart;
    290  1.1  jtc 				cval[clsses++]=oldloc;
    291  1.1  jtc 				break;
    292  1.1  jtc 			    case 12:    /* magic messages               */
    293  1.1  jtc 				if (oldloc>MAGSIZ)
    294  1.1  jtc 				{       printf("Too many magic msgs\n");
    295  1.1  jtc 					exit(0);
    296  1.1  jtc 				}
    297  1.1  jtc 				mtext[oldloc].seekadr=seekhere;
    298  1.1  jtc 				mtext[oldloc].txtlen=maystart-seekstart;
    299  1.1  jtc 				break;
    300  1.1  jtc 			    default:
    301  1.1  jtc 				printf("rdesc called with bad section\n");
    302  1.1  jtc 				exit(0);
    303  1.1  jtc 			}
    304  1.1  jtc 			seekhere += maystart-seekstart;
    305  1.1  jtc 		}
    306  1.1  jtc 		if (locc<0)
    307  1.1  jtc 		{       outsw=0;        /* turn off output              */
    308  1.1  jtc 			seekhere += 3;  /* -1<delimiter>                */
    309  1.1  jtc 			return;
    310  1.1  jtc 		}
    311  1.1  jtc 		if (sect!=5 || (locc>0 && locc<100))
    312  1.1  jtc 		{       if (oldloc!=locc)/* starting a new message       */
    313  1.1  jtc 				seekstart=maystart;
    314  1.1  jtc 			oldloc=locc;
    315  1.1  jtc 		}
    316  1.1  jtc 		FLUSHLF;                /* scan the line                */
    317  1.1  jtc 	}
    318  1.1  jtc }
    319  1.1  jtc 
    320  1.1  jtc 
    321  1.1  jtc rtrav()                                 /* read travel table            */
    322  1.1  jtc {       register int locc;
    323  1.1  jtc 	register struct travlist *t;
    324  1.1  jtc 	register char *s;
    325  1.1  jtc 	char buf[12];
    326  1.1  jtc 	int len,m,n,entries;
    327  1.1  jtc 	for (oldloc= -1;;)              /* get another line             */
    328  1.1  jtc 	{       if ((locc=rnum())!=oldloc && oldloc>=0) /* end of entry */
    329  1.1  jtc 		{
    330  1.1  jtc 			t->next = 0;    /* terminate the old entry      */
    331  1.1  jtc 		/*      printf("%d:%d entries\n",oldloc,entries);       */
    332  1.1  jtc 		/*      twrite(oldloc);                                 */
    333  1.1  jtc 		}
    334  1.1  jtc 		if (locc== -1) return;
    335  1.1  jtc 		if (locc!=oldloc)        /* getting a new entry         */
    336  1.1  jtc 		{       t=travel[locc]=(struct travlist *) malloc(sizeof (struct travlist));
    337  1.1  jtc 		/*      printf("New travel list for %d\n",locc);        */
    338  1.1  jtc 			entries=0;
    339  1.1  jtc 			oldloc=locc;
    340  1.1  jtc 		}
    341  1.1  jtc 		for (s=buf;; *s++)      /* get the newloc number /ASCII */
    342  1.1  jtc 			if ((*s=next())==TAB || *s==LF) break;
    343  1.1  jtc 		*s=0;
    344  1.1  jtc 		len=length(buf)-1;      /* quad long number handling    */
    345  1.1  jtc 	/*      printf("Newloc: %s (%d chars)\n",buf,len);              */
    346  1.1  jtc 		if (len<4)              /* no "m" conditions            */
    347  1.1  jtc 		{       m=0;
    348  1.1  jtc 			n=atoi(buf);    /* newloc mod 1000 = newloc     */
    349  1.1  jtc 		}
    350  1.1  jtc 		else                    /* a long integer               */
    351  1.1  jtc 		{       n=atoi(buf+len-3);
    352  1.1  jtc 			buf[len-3]=0;   /* terminate newloc/1000        */
    353  1.1  jtc 			m=atoi(buf);
    354  1.1  jtc 		}
    355  1.1  jtc 		while (breakch!=LF)     /* only do one line at a time   */
    356  1.1  jtc 		{       if (entries++) t=t->next=(struct travlist *) malloc(sizeof (struct travlist));
    357  1.1  jtc 			t->tverb=rnum();/* get verb from the file       */
    358  1.1  jtc 			t->tloc=n;      /* table entry mod 1000         */
    359  1.1  jtc 			t->conditions=m;/* table entry / 1000           */
    360  1.1  jtc 		/*      printf("entry %d for %d\n",entries,locc);       */
    361  1.1  jtc 		}
    362  1.1  jtc 	}
    363  1.1  jtc }
    364  1.1  jtc 
    365  1.1  jtc #ifdef DEBUG
    366  1.1  jtc 
    367  1.1  jtc twrite(loq)                             /* travel options from this loc */
    368  1.1  jtc int loq;
    369  1.1  jtc {       register struct travlist *t;
    370  1.1  jtc 	printf("If");
    371  1.1  jtc 	speak(&ltext[loq]);
    372  1.1  jtc 	printf("then\n");
    373  1.1  jtc 	for (t=travel[loq]; t!=0; t=t->next)
    374  1.1  jtc 	{       printf("verb %d takes you to ",t->tverb);
    375  1.1  jtc 		if (t->tloc<=300)
    376  1.1  jtc 			speak(&ltext[t->tloc]);
    377  1.1  jtc 		else if (t->tloc<=500)
    378  1.1  jtc 			printf("special code %d\n",t->tloc-300);
    379  1.1  jtc 		else
    380  1.1  jtc 			rspeak(t->tloc-500);
    381  1.1  jtc 		printf("under conditions %d\n",t->conditions);
    382  1.1  jtc 	}
    383  1.1  jtc }
    384  1.1  jtc 
    385  1.1  jtc #endif DEBUG
    386  1.1  jtc 
    387  1.1  jtc rvoc()
    388  1.1  jtc {       register char *s;               /* read the vocabulary          */
    389  1.1  jtc 	register int index;
    390  1.1  jtc 	char buf[6];
    391  1.1  jtc 	for (;;)
    392  1.1  jtc 	{       index=rnum();
    393  1.1  jtc 		if (index<0) break;
    394  1.1  jtc 		for (s=buf,*s=0;; s++)  /* get the word                 */
    395  1.1  jtc 			if ((*s=next())==TAB || *s=='\n' || *s==LF
    396  1.1  jtc 				|| *s==' ') break;
    397  1.1  jtc 			/* terminate word with newline, LF, tab, blank  */
    398  1.1  jtc 		if (*s!='\n' && *s!=LF) FLUSHLF;  /* can be comments    */
    399  1.1  jtc 		*s=0;
    400  1.1  jtc 	/*      printf("\"%s\"=%d\n",buf,index);*/
    401  1.1  jtc 		vocab(buf,-2,index);
    402  1.1  jtc 	}
    403  1.1  jtc /*	prht();	*/
    404  1.1  jtc }
    405  1.1  jtc 
    406  1.1  jtc 
    407  1.1  jtc rlocs()                                 /* initial object locations     */
    408  1.1  jtc {	for (;;)
    409  1.1  jtc 	{       if ((obj=rnum())<0) break;
    410  1.1  jtc 		plac[obj]=rnum();       /* initial loc for this obj     */
    411  1.1  jtc 		if (breakch==TAB)       /* there's another entry        */
    412  1.1  jtc 			fixd[obj]=rnum();
    413  1.1  jtc 		else    fixd[obj]=0;
    414  1.1  jtc 	}
    415  1.1  jtc }
    416  1.1  jtc 
    417  1.1  jtc rdflt()                                 /* default verb messages        */
    418  1.1  jtc {	for (;;)
    419  1.1  jtc 	{       if ((verb=rnum())<0) break;
    420  1.1  jtc 		actspk[verb]=rnum();
    421  1.1  jtc 	}
    422  1.1  jtc }
    423  1.1  jtc 
    424  1.1  jtc rliq()                                  /* liquid assets &c: cond bits  */
    425  1.1  jtc {       register int bitnum;
    426  1.1  jtc 	for (;;)                        /* read new bit list            */
    427  1.1  jtc 	{       if ((bitnum=rnum())<0) break;
    428  1.1  jtc 		for (;;)                /* read locs for bits           */
    429  1.1  jtc 		{       cond[rnum()] |= setbit[bitnum];
    430  1.1  jtc 			if (breakch==LF) break;
    431  1.1  jtc 		}
    432  1.1  jtc 	}
    433  1.1  jtc }
    434  1.1  jtc 
    435  1.1  jtc rhints()
    436  1.1  jtc {       register int hintnum,i;
    437  1.1  jtc 	hntmax=0;
    438  1.1  jtc 	for (;;)
    439  1.1  jtc 	{       if ((hintnum=rnum())<0) break;
    440  1.1  jtc 		for (i=1; i<5; i++)
    441  1.1  jtc 			hints[hintnum][i]=rnum();
    442  1.1  jtc 		if (hintnum>hntmax) hntmax=hintnum;
    443  1.1  jtc 	}
    444  1.1  jtc }
    445  1.1  jtc 
    446  1.1  jtc 
    447  1.1  jtc rspeak(msg)
    448  1.1  jtc int msg;
    449  1.1  jtc {       if (msg!=0) speak(&rtext[msg]);
    450  1.1  jtc }
    451  1.1  jtc 
    452  1.1  jtc 
    453  1.1  jtc mspeak(msg)
    454  1.1  jtc int msg;
    455  1.1  jtc {       if (msg!=0) speak(&mtext[msg]);
    456  1.1  jtc }
    457  1.1  jtc 
    458  1.1  jtc 
    459  1.1  jtc speak(msg)       /* read, decrypt, and print a message (not ptext)      */
    460  1.1  jtc struct text *msg;/* msg is a pointer to seek address and length of mess */
    461  1.1  jtc {
    462  1.1  jtc 	register char *s, nonfirst;
    463  1.1  jtc 
    464  1.1  jtc 	s = msg->seekadr;
    465  1.1  jtc 	nonfirst=0;
    466  1.1  jtc 	while (s - msg->seekadr < msg->txtlen)  /* read a line at a time */
    467  1.1  jtc 	{       tape=iotape;            /* restart decryption tape      */
    468  1.1  jtc 		while ((*s++ ^ *tape++) != TAB); /* read past loc num       */
    469  1.1  jtc 		/* assume tape is longer than location number           */
    470  1.1  jtc 		/*   plus the lookahead put together                    */
    471  1.1  jtc 		if ((*s ^ *tape) == '>' &&
    472  1.1  jtc 			(*(s+1) ^ *(tape+1)) == '$' &&
    473  1.1  jtc 			(*(s+2) ^ *(tape+2)) == '<') break;
    474  1.1  jtc 		if (blklin && !nonfirst++) putchar('\n');
    475  1.1  jtc 		do
    476  1.1  jtc 		{       if (*tape == 0) tape = iotape;/* rewind decryp tape */
    477  1.1  jtc 			putchar(*s ^ *tape);
    478  1.1  jtc 		} while ((*s++ ^ *tape++) != LF);   /* better end with LF   */
    479  1.1  jtc 	}
    480  1.1  jtc }
    481  1.1  jtc 
    482  1.1  jtc 
    483  1.1  jtc pspeak(m,skip) /* read, decrypt an print a ptext message              */
    484  1.1  jtc int m;         /* msg is the number of all the p msgs for this place  */
    485  1.1  jtc int skip;       /* assumes object 1 doesn't have prop 1, obj 2 no prop 2 &c*/
    486  1.1  jtc {
    487  1.1  jtc 	register char *s,nonfirst;
    488  1.1  jtc 	char *numst, save;
    489  1.1  jtc 	struct text *msg;
    490  1.1  jtc 	char *tbuf;
    491  1.1  jtc 
    492  1.1  jtc 	msg = &ptext[m];
    493  1.1  jtc 	if ((tbuf=(char *) malloc(msg->txtlen + 1)) == 0) bug(108);
    494  1.1  jtc 	memcpy(tbuf, msg->seekadr, msg->txtlen + 1);   /* Room to null */
    495  1.1  jtc 	s = tbuf;
    496  1.1  jtc 
    497  1.1  jtc 	nonfirst=0;
    498  1.1  jtc 	while (s - tbuf < msg->txtlen) /* read line at a time */
    499  1.1  jtc 	{       tape=iotape;            /* restart decryption tape      */
    500  1.1  jtc 		for (numst=s; (*s^= *tape++)!=TAB; s++); /* get number  */
    501  1.1  jtc 
    502  1.1  jtc 		save = *s; /* Temporarily trash the string (cringe) */
    503  1.1  jtc 		*s++ = 0; /* decrypting number within the string          */
    504  1.1  jtc 
    505  1.1  jtc 		if (atoi(numst) != 100 * skip && skip >= 0)
    506  1.1  jtc 		{       while ((*s++^*tape++)!=LF) /* flush the line    */
    507  1.1  jtc 				if (*tape==0) tape=iotape;
    508  1.1  jtc 			continue;
    509  1.1  jtc 		}
    510  1.1  jtc 		if ((*s^*tape)=='>' && (*(s+1)^*(tape+1))=='$' &&
    511  1.1  jtc 			(*(s+2)^*(tape+2))=='<') break;
    512  1.1  jtc 		if (blklin && ! nonfirst++) putchar('\n');
    513  1.1  jtc 		do
    514  1.1  jtc 		{       if (*tape==0) tape=iotape;
    515  1.1  jtc 			putchar(*s^*tape);
    516  1.1  jtc 		} while ((*s++^*tape++)!=LF);   /* better end with LF   */
    517  1.1  jtc 		if (skip<0) break;
    518  1.1  jtc 	}
    519  1.1  jtc 	free(tbuf);
    520  1.1  jtc }
    521