diff options
Diffstat (limited to 'larn/tok.c')
-rw-r--r-- | larn/tok.c | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/larn/tok.c b/larn/tok.c new file mode 100644 index 0000000..6bab595 --- /dev/null +++ b/larn/tok.c @@ -0,0 +1,235 @@ +/* $NetBSD: tok.c,v 1.11 2012/06/19 05:30:44 dholland Exp $ */ + +/* tok.c Larn is copyrighted 1986 by Noah Morgan. */ +#include <sys/cdefs.h> +#ifndef lint +__RCSID("$NetBSD: tok.c,v 1.11 2012/06/19 05:30:44 dholland Exp $"); +#endif /* not lint */ + +#include <sys/types.h> +#include <string.h> +#include <sys/ioctl.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/wait.h> +#include <ctype.h> +#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); +} |