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