#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include "extern.h"
#include "hdr.h"
void
getin(char *wrd1, size_t siz1, char *wrd2, size_t siz2)
{
char *s, *slast;
int ch, first;
*wrd2 = 0;
for (s = wrd1, first = 1, slast = wrd1 + siz1 - 1;;) {
if ((ch = getchar()) >= 'A' && ch <= 'Z')
ch = ch - ('A' - 'a');
switch (ch) {
case '\n':
*s = 0;
return;
case ' ':
if (s == wrd1 || s == wrd2)
continue;
*s = 0;
if (first) {
first = 0;
s = wrd2;
slast = wrd2 + siz2 - 1;
break;
} else {
FLUSHLINE;
*s = 0;
return;
}
case EOF:
printf("user closed input stream, quitting...\n");
exit(0);
default:
if (s == slast) {
printf("Give me a break!!\n");
*wrd1 = *wrd2 = 0;
FLUSHLINE;
return;
}
*s++ = ch;
}
}
}
int
yes(int x, int y, int z)
{
int result;
int ch;
for (;;) {
rspeak(x);
if ((ch = getchar())=='y')
result = TRUE;
else if (ch=='n')
result = FALSE;
else if (ch == EOF) {
printf("user closed input stream, quitting...\n");
exit(0);
}
if (ch != '\n')
FLUSHLINE;
if (ch == 'y' || ch == 'n')
break;
printf("Please answer the question.\n");
}
if (result == TRUE)
rspeak(y);
if (result == FALSE)
rspeak(z);
return (result);
}
int
yesm(int x, int y, int z)
{
int result;
int ch;
for (;;) {
mspeak(x);
if ((ch = getchar()) == 'y')
result = TRUE;
else if (ch == 'n')
result = FALSE;
else if (ch == EOF) {
printf("user closed input stream, quitting...\n");
exit(0);
}
if (ch != '\n')
FLUSHLINE;
if (ch == 'y' || ch == 'n')
break;
printf("Please answer the question.\n");
}
if (result == TRUE)
mspeak(y);
if (result == FALSE)
mspeak(z);
return (result);
}
char *inptr;
int outsw = 0;
const char iotape[] = "Ax3F'\003tt$8h\315qer*h\017nGKrX\207:!l";
const char *tape = iotape;
int
next(void)
{
int ch;
ch=(*inptr ^ random()) & 0xFF;
if (outsw) {
if (*tape == 0)
tape = iotape;
*inptr = ch ^ *tape++;
}
inptr++;
return (ch);
}
char breakch;
void
rdata(void)
{
int sect;
char ch;
inptr = data_file;
clsses = 1;
for (;;) {
sect = next() - '0';
#ifdef VERBOSE
printf("Section %c", sect + '0');
#endif
if ((ch = next()) != LF) {
FLUSHLF;
#ifdef VERBOSE
putchar(ch);
#endif
sect = 10 * sect + ch - '0';
}
#ifdef VERBOSE
putchar('\n');
#endif
switch (sect) {
case 0:
return;
case 1:
rdesc(1);
break;
case 2:
rdesc(2);
break;
case 3:
rtrav();
break;
case 4:
rvoc();
break;
case 5:
rdesc(5);
break;
case 6:
rdesc(6);
break;
case 7:
rlocs();
break;
case 8:
rdflt();
break;
case 9:
rliq();
break;
case 10:
rdesc(10);
break;
case 11:
rhints();
break;
case 12:
rdesc(12);
break;
default:
printf("Invalid data section number: %d\n", sect);
for (;;)
putchar(next());
}
if (breakch != LF)
FLUSHLF;
}
}
char nbf[12];
int
rnum(void)
{
char *s;
tape = iotape;
for (s = nbf, *s = 0;; s++)
if ((*s = next()) == TAB || *s == '\n' || *s == LF)
break;
breakch = *s;
*s = 0;
if (nbf[0] == '-')
return (-1);
return (atoi(nbf));
}
char *seekhere;
void
rdesc(int sect)
{
int locc;
char *seekstart, *maystart;
seekhere = inptr;
outsw = 1;
for (oldloc = -1, seekstart = seekhere;;) {
maystart = inptr;
if ((locc = rnum()) != oldloc && oldloc >= 0
&& !(sect == 5 && (locc == 0 || locc >= 100)))
{
switch (sect) {
case 1:
ltext[oldloc].seekadr = seekhere;
ltext[oldloc].txtlen = maystart - seekstart;
break;
case 2:
stext[oldloc].seekadr = seekhere;
stext[oldloc].txtlen = maystart - seekstart;
break;
case 5:
ptext[oldloc].seekadr = seekhere;
ptext[oldloc].txtlen = maystart - seekstart;
break;
case 6:
if (oldloc >= RTXSIZ)
errx(1, "Too many random msgs");
rtext[oldloc].seekadr = seekhere;
rtext[oldloc].txtlen = maystart - seekstart;
break;
case 10:
ctext[clsses].seekadr = seekhere;
ctext[clsses].txtlen = maystart - seekstart;
cval[clsses++] = oldloc;
break;
case 12:
if (oldloc >= MAGSIZ)
errx(1, "Too many magic msgs");
mtext[oldloc].seekadr = seekhere;
mtext[oldloc].txtlen = maystart - seekstart;
break;
default:
errx(1, "rdesc called with bad section");
}
seekhere += maystart - seekstart;
}
if (locc < 0) {
outsw = 0;
seekhere += 3;
return;
}
if (sect != 5 || (locc > 0 && locc < 100)) {
if (oldloc != locc)
seekstart = maystart;
oldloc = locc;
}
FLUSHLF;
}
}
void
rtrav(void)
{
int locc;
struct travlist *t;
char *s;
char buf[12];
int len, m, n, entries;
for (oldloc = -1;;) {
if ((locc = rnum()) != oldloc && oldloc >= 0) {
t->next = NULL;
}
if (locc == -1)
return;
if (locc != oldloc) {
t = travel[locc] = calloc(1, sizeof(*t));
if (t == NULL)
err(1, NULL);
entries = 0;
oldloc = locc;
}
for (s = buf; ; s++)
if ((*s = next()) == TAB || *s == LF)
break;
*s = 0;
len = length(buf) - 1;
if (len < 4) {
m = 0;
n = atoi(buf);
} else {
n = atoi(buf + len - 3);
buf[len - 3] = 0;
m = atoi(buf);
}
while (breakch != LF) {
if (t == NULL)
errx(1, "corrupt file");
if (entries++) {
t->next = calloc(1, sizeof (*t->next));
if (t->next == NULL)
err(1, NULL);
t = t->next;
}
t->tverb = rnum();
t->tloc = n;
t->conditions = m;
}
}
}
#ifdef DEBUG
void
twrite(int loq)
{
struct travlist *t;
printf("If");
speak(<ext[loq]);
printf("then\n");
for (t = travel[loq]; t != 0; t = t->next) {
printf("verb %d takes you to ", t->tverb);
if (t->tloc <= 300)
speak(<ext[t->tloc]);
else if (t->tloc <= 500)
printf("special code %d\n", t->tloc - 300);
else
rspeak(t->tloc - 500);
printf("under conditions %d\n", t->conditions);
}
}
#endif
void
rvoc(void)
{
char *s;
int index;
char buf[6];
for (;;) {
index = rnum();
if (index < 0)
break;
for (s = buf, *s = 0;; s++)
if ((*s = next()) == TAB || *s == '\n' || *s == LF
|| *s == ' ')
break;
if (*s != '\n' && *s != LF)
FLUSHLF;
*s = 0;
vocab(buf, -2, index);
}
}
void
rlocs(void)
{
for (;;) {
if ((obj = rnum()) < 0)
break;
plac[obj] = rnum();
if (breakch == TAB)
fixd[obj] = rnum();
else
fixd[obj] = 0;
}
}
void
rdflt(void)
{
for (;;) {
if ((verb = rnum()) < 0)
break;
actspk[verb] = rnum();
}
}
void
rliq(void)
{
int bitnum;
for (;;) {
if ((bitnum = rnum()) < 0)
break;
for (;;) {
cond[rnum()] |= setbit[bitnum];
if (breakch == LF)
break;
}
}
}
void
rhints(void)
{
int hintnum, i;
hntmax = 0;
for (;;) {
if ((hintnum = rnum()) < 0)
break;
for (i = 1; i < 5; i++)
hints[hintnum][i] = rnum();
if (hintnum > hntmax)
hntmax = hintnum;
}
}
void
rspeak(int msg)
{
if (msg != 0)
speak(&rtext[msg]);
}
void
mspeak(int msg)
{
if (msg != 0)
speak(&mtext[msg]);
}
void
speak(const struct text *msg)
{
char *s, nonfirst;
s = msg->seekadr;
nonfirst = 0;
while (s - msg->seekadr < msg->txtlen) {
tape = iotape;
while ((*s++ ^ *tape++) != TAB);
if ((*s ^ *tape) == '>' &&
(*(s + 1) ^ *(tape + 1)) == '$' &&
(*(s + 2) ^ *(tape + 2)) == '<')
break;
if (blklin && !nonfirst++)
putchar('\n');
do {
if (*tape == 0)
tape = iotape;
putchar(*s ^ *tape);
} while ((*s++ ^ *tape++) != LF);
}
}
void
pspeak(int m, int skip)
{
char *s, nonfirst;
char *numst, save;
struct text *msg;
char *tbuf;
msg = &ptext[m];
if ((tbuf = malloc(msg->txtlen + 1)) == 0)
err(1, NULL);
memcpy(tbuf, msg->seekadr, msg->txtlen + 1);
s = tbuf;
nonfirst = 0;
while (s - tbuf < msg->txtlen) {
tape = iotape;
for (numst = s; (*s ^= *tape++) != TAB; s++)
;
save = *s;
*s++ = 0;
if (atoi(numst) != 100 * skip && skip >= 0) {
while ((*s++ ^ * tape++) != LF)
if (*tape == 0)
tape = iotape;
continue;
}
if ((*s^ * tape) == '>' && (*(s + 1) ^ * (tape + 1)) == '$' &&
(*(s + 2) ^ * (tape + 2)) == '<')
break;
if (blklin && !nonfirst++)
putchar('\n');
do {
if (*tape == 0)
tape = iotape;
putchar(*s^ * tape);
} while ((*s++ ^ * tape++) != LF);
if (skip < 0)
break;
}
free(tbuf);
}