|
|
1.1 ! root 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(<ext[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(<ext[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: } ! 497:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.