Annotation of 43BSD/games/adventure/io.c, revision 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.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: }
        !           497: 

unix.superglobalmegacorp.com

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