[BACK]Return to io.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / games / adventure

Annotation of src/games/adventure/io.c, Revision 1.23

1.23    ! rillig      1: /*     $NetBSD: io.c,v 1.22 2009/08/25 06:56:52 dholland Exp $ */
1.2       cgd         2:
1.1       jtc         3: /*-
                      4:  * Copyright (c) 1991, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
                      6:  *
                      7:  * The game adventure was originally written in Fortran by Will Crowther
                      8:  * and Don Woods.  It was later translated to C and enhanced by Jim
                      9:  * Gillogly.  This code is derived from software contributed to Berkeley
                     10:  * by Jim Gillogly at The Rand Corporation.
                     11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer in the
                     19:  *    documentation and/or other materials provided with the distribution.
1.13      agc        20:  * 3. Neither the name of the University nor the names of its contributors
1.1       jtc        21:  *    may be used to endorse or promote products derived from this software
                     22:  *    without specific prior written permission.
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     34:  * SUCH DAMAGE.
                     35:  */
                     36:
1.4       christos   37: #include <sys/cdefs.h>
1.1       jtc        38: #ifndef lint
1.2       cgd        39: #if 0
1.1       jtc        40: static char sccsid[] = "@(#)io.c       8.1 (Berkeley) 5/31/93";
1.2       cgd        41: #else
1.23    ! rillig     42: __RCSID("$NetBSD: io.c,v 1.22 2009/08/25 06:56:52 dholland Exp $");
1.2       cgd        43: #endif
1.1       jtc        44: #endif /* not lint */
                     45:
                     46: /*      Re-coding of advent in C: file i/o and user i/o                 */
                     47:
1.9       hubertf    48: #include <err.h>
1.1       jtc        49: #include <stdio.h>
1.3       cgd        50: #include <string.h>
1.4       christos   51: #include <stdlib.h>
                     52: #include "hdr.h"
                     53: #include "extern.h"
1.1       jtc        54:
1.21      dholland   55: static int next(void);
                     56: static void rdesc(int);
1.22      dholland   57: static void rdefault(void);
1.21      dholland   58: static void rhints(void);
                     59: static void rliq(void);
                     60: static void rlocs(void);
                     61: static int rnum(void);
                     62: static void rtrav(void);
                     63: static void rvoc(void);
1.1       jtc        64:
1.16      jmc        65: /* get command from user        */
                     66: /* no prompt, usually           */
1.4       christos   67: void
1.16      jmc        68: getin(char **wrd1, char **wrd2)
1.6       lukem      69: {
                     70:        char   *s;
                     71:        static char wd1buf[MAXSTR], wd2buf[MAXSTR];
1.20      mrg        72:        int     first, numch, c;
1.6       lukem      73:
                     74:        *wrd1 = wd1buf;                         /* return ptr to internal str */
                     75:        *wrd2 = wd2buf;
                     76:        wd2buf[0] = 0;                          /* in case it isn't set here */
                     77:        for (s = wd1buf, first = 1, numch = 0;;) {
1.20      mrg        78:                c = getchar();
                     79:                if ((*s = (char)c) >= 'A' && *s <= 'Z')
1.6       lukem      80:                        *s = *s - ('A' - 'a');
                     81:                /* convert to upper case */
1.20      mrg        82:                switch (c) {                    /* start reading from user */
1.6       lukem      83:                case '\n':
                     84:                        *s = 0;
1.1       jtc        85:                        return;
1.6       lukem      86:                case ' ':
                     87:                        if (s == wd1buf || s == wd2buf) /* initial blank */
1.1       jtc        88:                                continue;
1.6       lukem      89:                        *s = 0;
                     90:                        if (first) {            /* finished 1st wd; start 2nd */
                     91:                                first = numch = 0;
                     92:                                s = wd2buf;
1.1       jtc        93:                                break;
1.6       lukem      94:                        } else {                /* finished 2nd word */
                     95:                                FLUSHLINE;
                     96:                                *s = 0;
1.1       jtc        97:                                return;
                     98:                        }
1.11      hubertf    99:                case EOF:
                    100:                        printf("user closed input stream, quitting...\n");
                    101:                        exit(0);
1.6       lukem     102:                default:
                    103:                        if (++numch >= MAXSTR) {        /* string too long */
                    104:                                printf("Give me a break!!\n");
                    105:                                wd1buf[0] = wd2buf[0] = 0;
1.1       jtc       106:                                FLUSHLINE;
                    107:                                return;
                    108:                        }
                    109:                        s++;
                    110:                }
                    111:        }
                    112: }
                    113:
1.16      jmc       114: /* confirm with rspeak          */
1.4       christos  115: int
1.16      jmc       116: yes(int x, int y, int z)
1.6       lukem     117: {
                    118:        int     result = TRUE;  /* pacify gcc */
1.11      hubertf   119:        int    ch;
1.6       lukem     120:        for (;;) {
                    121:                rspeak(x);      /* tell him what we want */
                    122:                if ((ch = getchar()) == 'y')
                    123:                        result = TRUE;
1.11      hubertf   124:                else if (ch == 'n')
                    125:                        result = FALSE;
                    126:                else if (ch == EOF) {
                    127:                        printf("user closed input stream, quitting...\n");
                    128:                        exit(0);
                    129:                }
1.1       jtc       130:                FLUSHLINE;
1.6       lukem     131:                if (ch == 'y' || ch == 'n')
                    132:                        break;
1.1       jtc       133:                printf("Please answer the question.\n");
                    134:        }
1.6       lukem     135:        if (result == TRUE)
                    136:                rspeak(y);
                    137:        if (result == FALSE)
                    138:                rspeak(z);
                    139:        return (result);
1.1       jtc       140: }
                    141:
1.16      jmc       142: /* confirm with mspeak          */
1.4       christos  143: int
1.16      jmc       144: yesm(int x, int y, int z)
1.6       lukem     145: {
                    146:        int     result = TRUE;  /* pacify gcc */
1.11      hubertf   147:        int    ch;
1.6       lukem     148:        for (;;) {
                    149:                mspeak(x);      /* tell him what we want */
                    150:                if ((ch = getchar()) == 'y')
                    151:                        result = TRUE;
1.11      hubertf   152:                else if (ch == 'n')
                    153:                        result = FALSE;
                    154:                else if (ch == EOF) {
                    155:                        printf("user closed input stream, quitting...\n");
                    156:                        exit(0);
                    157:                }
1.1       jtc       158:                FLUSHLINE;
1.6       lukem     159:                if (ch == 'y' || ch == 'n')
                    160:                        break;
1.1       jtc       161:                printf("Please answer the question.\n");
                    162:        }
1.6       lukem     163:        if (result == TRUE)
                    164:                mspeak(y);
                    165:        if (result == FALSE)
                    166:                mspeak(z);
                    167:        return (result);
1.1       jtc       168: }
                    169: /* FILE *inbuf,*outbuf; */
                    170:
1.21      dholland  171: static char *inptr;            /* Pointer into virtual disk    */
1.1       jtc       172:
1.21      dholland  173: static int outsw = 0;          /* putting stuff to data file?  */
1.1       jtc       174:
1.21      dholland  175: static const char    iotape[] = "Ax3F'\003tt$8h\315qer*h\017nGKrX\207:!l";
                    176: static const char   *tape = iotape;    /* pointer to encryption tape   */
1.1       jtc       177:
1.16      jmc       178: /* next virtual char, bump adr  */
1.21      dholland  179: static int
1.16      jmc       180: next(void)
1.23    ! rillig    181: {
1.6       lukem     182:        int     ch;
                    183:
1.16      jmc       184:        ch = (*inptr ^ random()) & 0xFF;        /* Decrypt input data  */
1.6       lukem     185:        if (outsw) {            /* putting data in tmp file     */
                    186:                if (*tape == 0)
                    187:                        tape = iotape;  /* rewind encryption tape       */
                    188:                *inptr = ch ^ *tape++;  /* re-encrypt and replace value */
1.1       jtc       189:        }
                    190:        inptr++;
1.6       lukem     191:        return (ch);
1.1       jtc       192: }
                    193:
1.21      dholland  194: static char breakch;           /* tell which char ended rnum   */
1.1       jtc       195:
1.16      jmc       196: /* "read" data from virtual file */
1.4       christos  197: void
1.16      jmc       198: rdata(void)
1.23    ! rillig    199: {
1.6       lukem     200:        int     sect;
                    201:        char    ch;
1.1       jtc       202:
1.6       lukem     203:        inptr = data_file;      /* Pointer to virtual data file */
                    204:        srandom(SEED);          /* which is lightly encrypted.  */
1.1       jtc       205:
1.22      dholland  206:        classes = 1;
1.6       lukem     207:        for (;;) {              /* read data sections           */
                    208:                sect = next() - '0';    /* 1st digit of section number  */
1.1       jtc       209: #ifdef VERBOSE
1.6       lukem     210:                printf("Section %c", sect + '0');
1.1       jtc       211: #endif
1.6       lukem     212:                if ((ch = next()) != LF) {      /* is there a second digit?     */
1.1       jtc       213:                        FLUSHLF;
                    214: #ifdef VERBOSE
                    215:                        putchar(ch);
                    216: #endif
1.6       lukem     217:                        sect = 10 * sect + ch - '0';
1.1       jtc       218:                }
                    219: #ifdef VERBOSE
                    220:                putchar('\n');
                    221: #endif
1.6       lukem     222:                switch (sect) {
                    223:                case 0: /* finished reading database    */
1.1       jtc       224:                        return;
1.6       lukem     225:                case 1: /* long form descriptions       */
1.1       jtc       226:                        rdesc(1);
                    227:                        break;
1.6       lukem     228:                case 2: /* short form descriptions      */
1.1       jtc       229:                        rdesc(2);
                    230:                        break;
1.6       lukem     231:                case 3: /* travel table                 */
                    232:                        rtrav();
                    233:                        break;
                    234:                case 4: /* vocabulary                   */
1.1       jtc       235:                        rvoc();
                    236:                        break;
1.6       lukem     237:                case 5: /* object descriptions          */
1.1       jtc       238:                        rdesc(5);
                    239:                        break;
1.6       lukem     240:                case 6: /* arbitrary messages           */
1.1       jtc       241:                        rdesc(6);
                    242:                        break;
1.6       lukem     243:                case 7: /* object locations             */
                    244:                        rlocs();
                    245:                        break;
                    246:                case 8: /* action defaults              */
1.22      dholland  247:                        rdefault();
1.6       lukem     248:                        break;
                    249:                case 9: /* liquid assets                */
                    250:                        rliq();
                    251:                        break;
                    252:                case 10:        /* class messages               */
1.1       jtc       253:                        rdesc(10);
                    254:                        break;
1.6       lukem     255:                case 11:        /* hints                        */
                    256:                        rhints();
                    257:                        break;
                    258:                case 12:        /* magic messages               */
1.1       jtc       259:                        rdesc(12);
                    260:                        break;
1.6       lukem     261:                default:
                    262:                        printf("Invalid data section number: %d\n", sect);
                    263:                        for (;;)
                    264:                                putchar(next());
1.1       jtc       265:                }
1.6       lukem     266:                if (breakch != LF)      /* routines return after "-1"   */
1.1       jtc       267:                        FLUSHLF;
                    268:        }
                    269: }
                    270:
1.21      dholland  271: static char nbf[12];
1.1       jtc       272:
1.16      jmc       273: /* read initial location num    */
1.21      dholland  274: static int
1.16      jmc       275: rnum(void)
1.23    ! rillig    276: {
1.6       lukem     277:        char   *s;
                    278:        tape = iotape;          /* restart encryption tape      */
                    279:        for (s = nbf, *s = 0;; s++)
                    280:                if ((*s = next()) == TAB || *s == '\n' || *s == LF)
                    281:                        break;
                    282:        breakch = *s;           /* save char for rtrav()        */
                    283:        *s = 0;                 /* got the number as ascii      */
                    284:        if (nbf[0] == '-')
                    285:                return (-1);    /* end of data                  */
                    286:        return (atoi(nbf));     /* convert it to integer        */
                    287: }
                    288:
1.21      dholland  289: static char *seekhere;
1.6       lukem     290:
1.16      jmc       291: /* read description-format msgs */
1.21      dholland  292: static void
1.16      jmc       293: rdesc(int sect)
1.6       lukem     294: {
                    295:        int     locc;
                    296:        char   *seekstart, *maystart;
                    297:
                    298:        seekhere = inptr;       /* Where are we in virtual file? */
                    299:        outsw = 1;              /* these msgs go into tmp file  */
                    300:        for (oldloc = -1, seekstart = seekhere;;) {
                    301:                maystart = inptr;       /* maybe starting new entry     */
1.16      jmc       302:                if ((locc = rnum()) != oldloc && oldloc >= 0 /* finished msg */
                    303:                    /* unless sect 5 */
                    304:                    && !(sect == 5 && (locc == 0 || locc >= 100))) {
1.6       lukem     305:                        switch (sect) { /* now put it into right table  */
                    306:                        case 1:/* long descriptions            */
                    307:                                ltext[oldloc].seekadr = seekhere;
                    308:                                ltext[oldloc].txtlen = maystart - seekstart;
1.1       jtc       309:                                break;
1.6       lukem     310:                        case 2:/* short descriptions           */
                    311:                                stext[oldloc].seekadr = seekhere;
                    312:                                stext[oldloc].txtlen = maystart - seekstart;
1.1       jtc       313:                                break;
1.6       lukem     314:                        case 5:/* object descriptions          */
                    315:                                ptext[oldloc].seekadr = seekhere;
                    316:                                ptext[oldloc].txtlen = maystart - seekstart;
1.1       jtc       317:                                break;
1.6       lukem     318:                        case 6:/* random messages              */
1.23    ! rillig    319:                                if (oldloc >= RTXSIZE)
1.10      hubertf   320:                                        errx(1,"Too many random msgs");
1.6       lukem     321:                                rtext[oldloc].seekadr = seekhere;
                    322:                                rtext[oldloc].txtlen = maystart - seekstart;
1.1       jtc       323:                                break;
1.6       lukem     324:                        case 10:        /* class messages               */
1.22      dholland  325:                                ctext[classes].seekadr = seekhere;
                    326:                                ctext[classes].txtlen = maystart - seekstart;
                    327:                                cval[classes++] = oldloc;
1.1       jtc       328:                                break;
1.6       lukem     329:                        case 12:        /* magic messages               */
1.22      dholland  330:                                if (oldloc >= MAGSIZE)
1.10      hubertf   331:                                        errx(1,"Too many magic msgs");
1.6       lukem     332:                                mtext[oldloc].seekadr = seekhere;
                    333:                                mtext[oldloc].txtlen = maystart - seekstart;
1.1       jtc       334:                                break;
1.6       lukem     335:                        default:
1.10      hubertf   336:                                errx(1,"rdesc called with bad section");
1.1       jtc       337:                        }
1.6       lukem     338:                        seekhere += maystart - seekstart;
1.1       jtc       339:                }
1.6       lukem     340:                if (locc < 0) {
                    341:                        outsw = 0;      /* turn off output              */
                    342:                        seekhere += 3;  /* -1<delimiter>                */
1.1       jtc       343:                        return;
                    344:                }
1.6       lukem     345:                if (sect != 5 || (locc > 0 && locc < 100)) {
1.16      jmc       346:                        if (oldloc != locc)     /* starting a new message */
1.6       lukem     347:                                seekstart = maystart;
                    348:                        oldloc = locc;
1.1       jtc       349:                }
1.6       lukem     350:                FLUSHLF;        /* scan the line                */
1.1       jtc       351:        }
                    352: }
                    353:
1.16      jmc       354: /* read travel table            */
1.21      dholland  355: static void
1.16      jmc       356: rtrav(void)
1.23    ! rillig    357: {
1.6       lukem     358:        int     locc;
1.5       lukem     359:        struct travlist *t = NULL;
1.6       lukem     360:        char   *s;
                    361:        char    buf[12];
                    362:        int     len, m, n, entries = 0;
                    363:
                    364:        for (oldloc = -1;;) {   /* get another line             */
1.23    ! rillig    365:                /* end of entry */
1.17      christos  366:                if ((locc = rnum()) != oldloc && oldloc >= 0 && t) {
1.6       lukem     367:                        t->next = 0;    /* terminate the old entry      */
                    368:                        /* printf("%d:%d entries\n",oldloc,entries);       */
                    369:                        /* twrite(oldloc);                                 */
                    370:                }
                    371:                if (locc == -1)
                    372:                        return;
                    373:                if (locc != oldloc) {   /* getting a new entry         */
1.19      christos  374:                        t = travel[locc] = calloc(1, sizeof(*t));
                    375:                        if (t == NULL)
1.12      jsm       376:                                err(1, NULL);
1.6       lukem     377:                        /* printf("New travel list for %d\n",locc);        */
                    378:                        entries = 0;
                    379:                        oldloc = locc;
                    380:                }
                    381:                for (s = buf;; s++)     /* get the newloc number /ASCII */
                    382:                        if ((*s = next()) == TAB || *s == LF)
                    383:                                break;
                    384:                *s = 0;
                    385:                len = length(buf) - 1;  /* quad long number handling    */
                    386:                /* printf("Newloc: %s (%d chars)\n",buf,len);              */
                    387:                if (len < 4) {  /* no "m" conditions            */
                    388:                        m = 0;
                    389:                        n = atoi(buf);  /* newloc mod 1000 = newloc     */
                    390:                } else {        /* a long integer               */
                    391:                        n = atoi(buf + len - 3);
1.16      jmc       392:                        buf[len - 3] = 0;       /* terminate newloc/1000  */
1.6       lukem     393:                        m = atoi(buf);
                    394:                }
                    395:                while (breakch != LF) { /* only do one line at a time   */
1.19      christos  396:                        if (t == NULL)
                    397:                                abort();
                    398:                        if (entries++) {
                    399:                                t->next = calloc(1, sizeof(*t));
1.17      christos  400:                                if (t->next == NULL)
1.12      jsm       401:                                        err(1, NULL);
1.17      christos  402:                                t = t->next;
1.9       hubertf   403:                        }
1.16      jmc       404:                        t->tverb = rnum();      /* get verb from the file */
1.6       lukem     405:                        t->tloc = n;    /* table entry mod 1000         */
1.16      jmc       406:                        t->conditions = m;      /* table entry / 1000   */
                    407:                        /* printf("entry %d for %d\n",entries,locc);    */
1.1       jtc       408:                }
                    409:        }
                    410: }
                    411: #ifdef DEBUG
                    412:
1.16      jmc       413: /* travel options from this loc */
1.4       christos  414: void
1.16      jmc       415: twrite(int loq)
1.6       lukem     416: {
                    417:        struct travlist *t;
1.1       jtc       418:        printf("If");
                    419:        speak(&ltext[loq]);
                    420:        printf("then\n");
1.6       lukem     421:        for (t = travel[loq]; t != 0; t = t->next) {
                    422:                printf("verb %d takes you to ", t->tverb);
                    423:                if (t->tloc <= 300)
1.1       jtc       424:                        speak(&ltext[t->tloc]);
                    425:                else
1.6       lukem     426:                        if (t->tloc <= 500)
                    427:                                printf("special code %d\n", t->tloc - 300);
                    428:                        else
                    429:                                rspeak(t->tloc - 500);
                    430:                printf("under conditions %d\n", t->conditions);
1.1       jtc       431:        }
                    432: }
1.6       lukem     433: #endif                         /* DEBUG */
1.1       jtc       434:
1.16      jmc       435: /* read the vocabulary          */
1.21      dholland  436: static void
1.16      jmc       437: rvoc(void)
1.6       lukem     438: {
1.16      jmc       439:        char   *s;
                    440:        int     idx;
1.6       lukem     441:        char    buf[6];
                    442:        for (;;) {
1.16      jmc       443:                idx = rnum();
                    444:                if (idx < 0)
1.6       lukem     445:                        break;
1.16      jmc       446:                for (s = buf, *s = 0;; s++)     /* get the word  */
1.6       lukem     447:                        if ((*s = next()) == TAB || *s == '\n' || *s == LF
                    448:                            || *s == ' ')
                    449:                                break;
                    450:                /* terminate word with newline, LF, tab, blank  */
                    451:                if (*s != '\n' && *s != LF)
                    452:                        FLUSHLF;/* can be comments    */
                    453:                *s = 0;
1.16      jmc       454:                /* printf("\"%s\"=%d\n",buf,idx); */
                    455:                vocab(buf, -2, idx);
1.1       jtc       456:        }
                    457: /*     prht(); */
                    458: }
                    459:
1.16      jmc       460: /* initial object locations     */
1.21      dholland  461: static void
1.16      jmc       462: rlocs(void)
1.23    ! rillig    463: {
1.6       lukem     464:        for (;;) {
                    465:                if ((obj = rnum()) < 0)
                    466:                        break;
                    467:                plac[obj] = rnum();     /* initial loc for this obj     */
                    468:                if (breakch == TAB)     /* there's another entry        */
                    469:                        fixd[obj] = rnum();
                    470:                else
                    471:                        fixd[obj] = 0;
1.1       jtc       472:        }
                    473: }
                    474:
1.16      jmc       475: /* default verb messages        */
1.21      dholland  476: static void
1.22      dholland  477: rdefault(void)
1.23    ! rillig    478: {
1.6       lukem     479:        for (;;) {
                    480:                if ((verb = rnum()) < 0)
                    481:                        break;
1.22      dholland  482:                actspeak[verb] = rnum();
1.1       jtc       483:        }
                    484: }
                    485:
1.16      jmc       486: /* liquid assets &c: cond bits  */
1.21      dholland  487: static void
1.16      jmc       488: rliq(void)
1.23    ! rillig    489: {
1.6       lukem     490:        int     bitnum;
                    491:        for (;;) {              /* read new bit list            */
                    492:                if ((bitnum = rnum()) < 0)
                    493:                        break;
                    494:                for (;;) {      /* read locs for bits           */
1.18      christos  495:                        int n = rnum();
                    496:                        if (n < 0)
                    497:                                break;
                    498:                        cond[n] |= setbit[bitnum];
1.6       lukem     499:                        if (breakch == LF)
                    500:                                break;
1.1       jtc       501:                }
                    502:        }
                    503: }
                    504:
1.21      dholland  505: static void
1.16      jmc       506: rhints(void)
1.6       lukem     507: {
                    508:        int     hintnum, i;
1.22      dholland  509:        hintmax = 0;
1.6       lukem     510:        for (;;) {
                    511:                if ((hintnum = rnum()) < 0)
                    512:                        break;
                    513:                for (i = 1; i < 5; i++)
                    514:                        hints[hintnum][i] = rnum();
1.22      dholland  515:                if (hintnum > hintmax)
                    516:                        hintmax = hintnum;
1.1       jtc       517:        }
                    518: }
                    519:
                    520:
1.4       christos  521: void
1.16      jmc       522: rspeak(int msg)
1.6       lukem     523: {
                    524:        if (msg != 0)
                    525:                speak(&rtext[msg]);
1.1       jtc       526: }
                    527:
                    528:
1.4       christos  529: void
1.16      jmc       530: mspeak(int msg)
1.6       lukem     531: {
                    532:        if (msg != 0)
                    533:                speak(&mtext[msg]);
1.1       jtc       534: }
                    535:
                    536:
1.16      jmc       537: /* read, decrypt, and print a message (not ptext)      */
                    538: /* msg is a pointer to seek address and length of mess */
1.4       christos  539: void
1.16      jmc       540: speak(const struct text *msg)
1.1       jtc       541: {
1.6       lukem     542:        char   *s, nonfirst;
1.1       jtc       543:
                    544:        s = msg->seekadr;
1.6       lukem     545:        nonfirst = 0;
1.16      jmc       546:        while (s - msg->seekadr < msg->txtlen) { /* read a line at a time */
1.6       lukem     547:                tape = iotape;  /* restart decryption tape      */
1.16      jmc       548:                while ((*s++ ^ *tape++) != TAB); /* read past loc num       */
1.1       jtc       549:                /* assume tape is longer than location number           */
1.6       lukem     550:                /* plus the lookahead put together                    */
1.1       jtc       551:                if ((*s ^ *tape) == '>' &&
1.6       lukem     552:                    (*(s + 1) ^ *(tape + 1)) == '$' &&
                    553:                    (*(s + 2) ^ *(tape + 2)) == '<')
                    554:                        break;
                    555:                if (blklin && !nonfirst++)
                    556:                        putchar('\n');
                    557:                do {
                    558:                        if (*tape == 0)
                    559:                                tape = iotape;  /* rewind decryp tape */
1.1       jtc       560:                        putchar(*s ^ *tape);
1.16      jmc       561:                } while ((*s++ ^ *tape++) != LF); /* better end with LF   */
1.1       jtc       562:        }
                    563: }
                    564:
1.16      jmc       565: /* read, decrypt and print a ptext message  */
                    566: /* msg is the number of all the p msgs for this place  */
                    567: /* assumes object 1 doesn't have prop 1, obj 2 no prop 2 &c */
1.4       christos  568: void
1.16      jmc       569: pspeak(int m, int skip)
1.1       jtc       570: {
1.6       lukem     571:        char   *s, nonfirst;
1.16      jmc       572:        char   *numst;
1.1       jtc       573:        struct text *msg;
1.6       lukem     574:        char   *tbuf;
1.1       jtc       575:
                    576:        msg = &ptext[m];
1.9       hubertf   577:        if ((tbuf = (char *) malloc(msg->txtlen + 1)) == NULL)
1.12      jsm       578:                err(1, NULL);
1.6       lukem     579:        memcpy(tbuf, msg->seekadr, msg->txtlen + 1);    /* Room to null */
1.1       jtc       580:        s = tbuf;
                    581:
1.6       lukem     582:        nonfirst = 0;
                    583:        while (s - tbuf < msg->txtlen) {        /* read line at a time */
                    584:                tape = iotape;  /* restart decryption tape      */
1.16      jmc       585:                for (numst = s; (*s ^= *tape++) != TAB; s++); /* get number  */
1.6       lukem     586:
1.16      jmc       587:                                /* Temporarily trash the string (cringe) */
                    588:                *s++ = 0;       /* decrypting number within the string   */
1.6       lukem     589:
                    590:                if (atoi(numst) != 100 * skip && skip >= 0) {
                    591:                        while ((*s++ ^ *tape++) != LF)  /* flush the line    */
                    592:                                if (*tape == 0)
                    593:                                        tape = iotape;
1.1       jtc       594:                        continue;
                    595:                }
1.6       lukem     596:                if ((*s ^ *tape) == '>' && (*(s + 1) ^ *(tape + 1)) == '$' &&
                    597:                    (*(s + 2) ^ *(tape + 2)) == '<')
                    598:                        break;
                    599:                if (blklin && !nonfirst++)
                    600:                        putchar('\n');
                    601:                do {
                    602:                        if (*tape == 0)
                    603:                                tape = iotape;
                    604:                        putchar(*s ^ *tape);
1.16      jmc       605:                } while ((*s++ ^ *tape++) != LF); /* better end with LF   */
1.6       lukem     606:                if (skip < 0)
                    607:                        break;
1.1       jtc       608:        }
                    609:        free(tbuf);
                    610: }

CVSweb <webmaster@jp.NetBSD.org>