Annotation of 43BSDReno/games/adventure/io.c, revision 1.1.1.1

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.2     88/09/22        ";
                      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: }
                    497: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.