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

Defined functions

confirm defined in line 53; used 1 times
doseek defined in line 411; used 2 times
mspeak defined in line 405; used 10 times
next defined in line 108; used 11 times
pspeak defined in line 465; used 10 times
rdata defined in line 123; used 1 times
rdesc defined in line 206; used 6 times
rdflt defined in line 369; used 1 times
rhints defined in line 387; used 1 times
rliq defined in line 376; used 1 times
rlocs defined in line 359; used 1 times
rnum defined in line 192; used 13 times
rspeak defined in line 399; used 53 times
rtrav defined in line 274; used 1 times
rvoc defined in line 339; used 1 times
speak defined in line 438; used 6 times
twrite defined in line 319; never used
yesm defined in line 82; used 1 times

Defined variables

adrptr defined in line 102; used 3 times
breakch defined in line 120; used 5 times
iotape defined in line 105; used 8 times
nbf defined in line 189; used 3 times
outsw defined in line 103; used 3 times
sccsid defined in line 4; never used
seekhere defined in line 204; used 9 times
tape defined in line 106; used 25 times
Last modified: 1982-06-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2013
Valid CSS Valid XHTML 1.0 Strict