/* $NetBSD: tok.c,v 1.11 2012/06/19 05:30:44 dholland Exp $ */ /* tok.c Larn is copyrighted 1986 by Noah Morgan. */ #include #ifndef lint __RCSID("$NetBSD: tok.c,v 1.11 2012/06/19 05:30:44 dholland Exp $"); #endif /* not lint */ #include #include #include #include #include #include #include #include "header.h" #include "extern.h" /* Keystrokes (roughly) between checkpoints */ #define CHECKPOINT_INTERVAL 400 static char lastok = 0; int yrepcount = 0; #ifndef FLUSHNO #define FLUSHNO 5 #endif /* FLUSHNO */ static int flushno = FLUSHNO; /* input queue flushing threshold */ #define MAXUM 52 /* maximum number of user re-named monsters */ #define MAXMNAME 40 /* max length of a monster re-name */ static char usermonster[MAXUM][MAXMNAME]; /* the user named monster * name goes here */ static u_char usermpoint = 0; /* the user monster pointer */ /* lexical analyzer for larn */ int yylex(void) { char cc; int ic; if (hit2flag) { hit2flag = 0; yrepcount = 0; return (' '); } if (yrepcount > 0) { --yrepcount; return (lastok); } else yrepcount = 0; if (yrepcount == 0) { bottomdo(); showplayer(); } /* show where the player is */ lflush(); while (1) { c[BYTESIN]++; /* check for periodic checkpointing */ if (ckpflag) if ((c[BYTESIN] % CHECKPOINT_INTERVAL) == 0) { #ifndef DOCHECKPOINTS savegame(ckpfile); #else wait(0); /* wait for other forks to * finish */ if (fork() == 0) { savegame(ckpfile); exit(); } #endif } do { /* if keyboard input buffer is too big, flush * some of it */ ioctl(0, FIONREAD, &ic); if (ic > flushno) read(0, &cc, 1); } while (ic > flushno); if (read(0, &cc, 1) != 1) return (lastok = -1); if (cc == 'Y' - 64) { /* control Y -- shell escape */ resetscroll(); clear();/* scrolling region, home, clear, no * attributes */ if ((ic = fork()) == 0) { /* child */ execl("/bin/csh", "/bin/csh", NULL); exit(1); } wait(0); if (ic < 0) { /* error */ write(2, "Can't fork off a shell!\n", 25); sleep(2); } setscroll(); return (lastok = 'L' - 64); /* redisplay screen */ } if ((cc <= '9') && (cc >= '0')) { yrepcount = yrepcount * 10 + cc - '0'; } else { if (yrepcount > 0) --yrepcount; return (lastok = cc); } } } /* * flushall() Function to flush all type-ahead in the input buffer */ void flushall(void) { char cc; int ic; for (;;) { /* if keyboard input buffer is too big, flush * some of it */ ioctl(0, FIONREAD, &ic); if (ic <= 0) return; while (ic > 0) { read(0, &cc, 1); --ic; } /* gobble up the byte */ } } /* function to set the desired hardness enter with hard= -1 for default hardness, else any desired hardness */ void sethard(int hard) { int j, k, i; struct monst *mp; j = c[HARDGAME]; hashewon(); if (restorflag == 0) { /* don't set c[HARDGAME] if restoring game */ if (hard >= 0) c[HARDGAME] = hard; } else c[HARDGAME] = j;/* set c[HARDGAME] to proper value if * restoring game */ if ((k = c[HARDGAME]) != 0) for (j = 0; j <= MAXMONST + 8; j++) { mp = &monster[j]; i = ((6 + k) * mp->hitpoints + 1) / 6; mp->hitpoints = (i < 0) ? 32767 : i; i = ((6 + k) * mp->damage + 1) / 5; mp->damage = (i > 127) ? 127 : i; i = (10 * mp->gold) / (10 + k); mp->gold = (i > 32767) ? 32767 : i; i = mp->armorclass - k; mp->armorclass = (i < -127) ? -127 : i; i = (7 * mp->experience) / (7 + k) + 1; mp->experience = (i <= 0) ? 1 : i; } } /* function to read and process the larn options file */ void readopts(void) { const char *i; int j, k; int flag; flag = 1; /* set to 0 if a name is specified */ if (lopen(optsfile) < 0) { strcpy(logname, loginname); return; /* user name if no character name */ } i = " "; while (*i) { if ((i = lgetw()) == NULL) break; /* check for EOF */ while ((*i == ' ') || (*i == '\t')) i++; /* eat leading whitespace */ if (strcmp(i, "bold-objects") == 0) boldon = 1; else if (strcmp(i, "enable-checkpointing") == 0) ckpflag = 1; else if (strcmp(i, "inverse-objects") == 0) boldon = 0; else if (strcmp(i, "female") == 0) sex = 0; /* male or female */ else if (strcmp(i, "monster:") == 0) { /* name favorite monster */ if ((i = lgetw()) == 0) break; strlcpy(usermonster[usermpoint], i, MAXMNAME); if (usermpoint >= MAXUM) continue; /* defined all of em */ if (isalpha(j = usermonster[usermpoint][0])) { for (k = 1; k < MAXMONST + 8; k++) /* find monster */ if (monstnamelist[k] == j) { monster[k].name = &usermonster[usermpoint++][0]; break; } } } else if (strcmp(i, "male") == 0) sex = 1; else if (strcmp(i, "name:") == 0) { /* defining players name */ if ((i = lgetw()) == 0) break; strlcpy(logname, i, LOGNAMESIZE); flag = 0; } else if (strcmp(i, "no-introduction") == 0) nowelcome = 1; else if (strcmp(i, "no-beep") == 0) nobeep = 1; else if (strcmp(i, "process-name:") == 0) { if ((i = lgetw()) == 0) break; strlcpy(psname, i, PSNAMESIZE); } else if (strcmp(i, "play-day-play") == 0) { /* bypass time restrictions: ignored */ } else if (strcmp(i, "savefile:") == 0) { /* defining savefilename */ if ((i = lgetw()) == 0) break; strcpy(savefilename, i); flag = 0; } } if (flag) strcpy(logname, loginname); }