1*c34afa68Sdholland /* $NetBSD: tok.c,v 1.11 2012/06/19 05:30:44 dholland Exp $ */
2210cab45Smycroft
361f28255Scgd /* tok.c Larn is copyrighted 1986 by Noah Morgan. */
4a8fba37dSchristos #include <sys/cdefs.h>
5a8fba37dSchristos #ifndef lint
6*c34afa68Sdholland __RCSID("$NetBSD: tok.c,v 1.11 2012/06/19 05:30:44 dholland Exp $");
7a8fba37dSchristos #endif /* not lint */
8a8fba37dSchristos
961f28255Scgd #include <sys/types.h>
10c4816c32Scgd #include <string.h>
11a8fba37dSchristos #include <sys/ioctl.h>
12a8fba37dSchristos #include <stdlib.h>
13a8fba37dSchristos #include <unistd.h>
14a8fba37dSchristos #include <sys/wait.h>
155c104910Sdholland #include <ctype.h>
16a8fba37dSchristos #include "header.h"
17a8fba37dSchristos #include "extern.h"
1861f28255Scgd
19f5334b08Sdholland /* Keystrokes (roughly) between checkpoints */
20f5334b08Sdholland #define CHECKPOINT_INTERVAL 400
21f5334b08Sdholland
2261f28255Scgd static char lastok = 0;
23b6e0b3d3Sdholland int yrepcount = 0;
2461f28255Scgd #ifndef FLUSHNO
2561f28255Scgd #define FLUSHNO 5
26a8fba37dSchristos #endif /* FLUSHNO */
2761f28255Scgd static int flushno = FLUSHNO; /* input queue flushing threshold */
2861f28255Scgd #define MAXUM 52 /* maximum number of user re-named monsters */
2961f28255Scgd #define MAXMNAME 40 /* max length of a monster re-name */
30a8fba37dSchristos static char usermonster[MAXUM][MAXMNAME]; /* the user named monster
31a8fba37dSchristos * name goes here */
32a8fba37dSchristos static u_char usermpoint = 0; /* the user monster pointer */
3361f28255Scgd
3461f28255Scgd /*
3561f28255Scgd lexical analyzer for larn
3661f28255Scgd */
37a8fba37dSchristos int
yylex(void)38*c34afa68Sdholland yylex(void)
3961f28255Scgd {
4061f28255Scgd char cc;
4161f28255Scgd int ic;
42a8fba37dSchristos if (hit2flag) {
43a8fba37dSchristos hit2flag = 0;
44a8fba37dSchristos yrepcount = 0;
45a8fba37dSchristos return (' ');
46a8fba37dSchristos }
47a8fba37dSchristos if (yrepcount > 0) {
48a8fba37dSchristos --yrepcount;
49a8fba37dSchristos return (lastok);
50a8fba37dSchristos } else
51a8fba37dSchristos yrepcount = 0;
52a8fba37dSchristos if (yrepcount == 0) {
53a8fba37dSchristos bottomdo();
54a8fba37dSchristos showplayer();
55a8fba37dSchristos } /* show where the player is */
5661f28255Scgd lflush();
57a8fba37dSchristos while (1) {
5861f28255Scgd c[BYTESIN]++;
59f5334b08Sdholland /* check for periodic checkpointing */
6061f28255Scgd if (ckpflag)
61f5334b08Sdholland if ((c[BYTESIN] % CHECKPOINT_INTERVAL) == 0) {
6261f28255Scgd #ifndef DOCHECKPOINTS
6361f28255Scgd savegame(ckpfile);
6461f28255Scgd #else
65a8fba37dSchristos wait(0); /* wait for other forks to
66a8fba37dSchristos * finish */
67a8fba37dSchristos if (fork() == 0) {
68a8fba37dSchristos savegame(ckpfile);
69a8fba37dSchristos exit();
70a8fba37dSchristos }
7161f28255Scgd #endif
7261f28255Scgd }
73a8fba37dSchristos do { /* if keyboard input buffer is too big, flush
74a8fba37dSchristos * some of it */
7561f28255Scgd ioctl(0, FIONREAD, &ic);
76a8fba37dSchristos if (ic > flushno)
77a8fba37dSchristos read(0, &cc, 1);
7861f28255Scgd }
7961f28255Scgd while (ic > flushno);
8061f28255Scgd
81a8fba37dSchristos if (read(0, &cc, 1) != 1)
82a8fba37dSchristos return (lastok = -1);
8361f28255Scgd
84a8fba37dSchristos if (cc == 'Y' - 64) { /* control Y -- shell escape */
85a8fba37dSchristos resetscroll();
86a8fba37dSchristos clear();/* scrolling region, home, clear, no
87a8fba37dSchristos * attributes */
88a8fba37dSchristos if ((ic = fork()) == 0) { /* child */
894bc6feceSmrg execl("/bin/csh", "/bin/csh", NULL);
90a8fba37dSchristos exit(1);
9161f28255Scgd }
9261f28255Scgd wait(0);
93a8fba37dSchristos if (ic < 0) { /* error */
94a8fba37dSchristos write(2, "Can't fork off a shell!\n", 25);
95a8fba37dSchristos sleep(2);
9661f28255Scgd }
9761f28255Scgd setscroll();
9861f28255Scgd return (lastok = 'L' - 64); /* redisplay screen */
9961f28255Scgd }
100a8fba37dSchristos if ((cc <= '9') && (cc >= '0')) {
101a8fba37dSchristos yrepcount = yrepcount * 10 + cc - '0';
102a8fba37dSchristos } else {
103a8fba37dSchristos if (yrepcount > 0)
104a8fba37dSchristos --yrepcount;
105a8fba37dSchristos return (lastok = cc);
106a8fba37dSchristos }
10761f28255Scgd }
10861f28255Scgd }
10961f28255Scgd
11061f28255Scgd /*
11161f28255Scgd * flushall() Function to flush all type-ahead in the input buffer
11261f28255Scgd */
113a8fba37dSchristos void
flushall(void)114*c34afa68Sdholland flushall(void)
11561f28255Scgd {
11661f28255Scgd char cc;
11761f28255Scgd int ic;
118a8fba37dSchristos for (;;) { /* if keyboard input buffer is too big, flush
119a8fba37dSchristos * some of it */
12061f28255Scgd ioctl(0, FIONREAD, &ic);
121a8fba37dSchristos if (ic <= 0)
122a8fba37dSchristos return;
123a8fba37dSchristos while (ic > 0) {
124a8fba37dSchristos read(0, &cc, 1);
125a8fba37dSchristos --ic;
126a8fba37dSchristos } /* gobble up the byte */
12761f28255Scgd }
12861f28255Scgd }
12961f28255Scgd
13061f28255Scgd /*
13161f28255Scgd function to set the desired hardness
13261f28255Scgd enter with hard= -1 for default hardness, else any desired hardness
13361f28255Scgd */
134a8fba37dSchristos void
sethard(int hard)135*c34afa68Sdholland sethard(int hard)
13661f28255Scgd {
137a8fba37dSchristos int j, k, i;
138f5334b08Sdholland struct monst *mp;
139f5334b08Sdholland
140a8fba37dSchristos j = c[HARDGAME];
141a8fba37dSchristos hashewon();
142a8fba37dSchristos if (restorflag == 0) { /* don't set c[HARDGAME] if restoring game */
143a8fba37dSchristos if (hard >= 0)
144a8fba37dSchristos c[HARDGAME] = hard;
145a8fba37dSchristos } else
146a8fba37dSchristos c[HARDGAME] = j;/* set c[HARDGAME] to proper value if
147a8fba37dSchristos * restoring game */
14861f28255Scgd
149a8fba37dSchristos if ((k = c[HARDGAME]) != 0)
150a8fba37dSchristos for (j = 0; j <= MAXMONST + 8; j++) {
151f5334b08Sdholland mp = &monster[j];
152f5334b08Sdholland i = ((6 + k) * mp->hitpoints + 1) / 6;
153f5334b08Sdholland mp->hitpoints = (i < 0) ? 32767 : i;
154f5334b08Sdholland i = ((6 + k) * mp->damage + 1) / 5;
155f5334b08Sdholland mp->damage = (i > 127) ? 127 : i;
156f5334b08Sdholland i = (10 * mp->gold) / (10 + k);
157f5334b08Sdholland mp->gold = (i > 32767) ? 32767 : i;
158f5334b08Sdholland i = mp->armorclass - k;
159f5334b08Sdholland mp->armorclass = (i < -127) ? -127 : i;
160f5334b08Sdholland i = (7 * mp->experience) / (7 + k) + 1;
161f5334b08Sdholland mp->experience = (i <= 0) ? 1 : i;
16261f28255Scgd }
16361f28255Scgd }
16461f28255Scgd
16561f28255Scgd /*
16661f28255Scgd function to read and process the larn options file
16761f28255Scgd */
168a8fba37dSchristos void
readopts(void)169*c34afa68Sdholland readopts(void)
17061f28255Scgd {
1719cc7e274Sdholland const char *i;
172a8fba37dSchristos int j, k;
17361f28255Scgd int flag;
174f5334b08Sdholland
175f5334b08Sdholland flag = 1; /* set to 0 if a name is specified */
176f5334b08Sdholland
177a8fba37dSchristos if (lopen(optsfile) < 0) {
178a8fba37dSchristos strcpy(logname, loginname);
179a8fba37dSchristos return; /* user name if no character name */
18061f28255Scgd }
18161f28255Scgd i = " ";
182a8fba37dSchristos while (*i) {
1839cc7e274Sdholland if ((i = lgetw()) == NULL)
184a8fba37dSchristos break; /* check for EOF */
185a8fba37dSchristos while ((*i == ' ') || (*i == '\t'))
186a8fba37dSchristos i++; /* eat leading whitespace */
187f5334b08Sdholland
188a8fba37dSchristos if (strcmp(i, "bold-objects") == 0)
189a8fba37dSchristos boldon = 1;
190f5334b08Sdholland else if (strcmp(i, "enable-checkpointing") == 0)
191a8fba37dSchristos ckpflag = 1;
192f5334b08Sdholland else if (strcmp(i, "inverse-objects") == 0)
193a8fba37dSchristos boldon = 0;
194f5334b08Sdholland else if (strcmp(i, "female") == 0)
195a8fba37dSchristos sex = 0; /* male or female */
196f5334b08Sdholland else if (strcmp(i, "monster:") == 0) { /* name favorite monster */
197a8fba37dSchristos if ((i = lgetw()) == 0)
198a8fba37dSchristos break;
1999cc7e274Sdholland strlcpy(usermonster[usermpoint], i, MAXMNAME);
200a8fba37dSchristos if (usermpoint >= MAXUM)
201f5334b08Sdholland continue; /* defined all of em */
202a8fba37dSchristos if (isalpha(j = usermonster[usermpoint][0])) {
20361f28255Scgd for (k = 1; k < MAXMONST + 8; k++) /* find monster */
204a8fba37dSchristos if (monstnamelist[k] == j) {
20561f28255Scgd monster[k].name = &usermonster[usermpoint++][0];
20661f28255Scgd break;
20761f28255Scgd }
20861f28255Scgd }
209a8fba37dSchristos } else if (strcmp(i, "male") == 0)
210a8fba37dSchristos sex = 1;
211f5334b08Sdholland else if (strcmp(i, "name:") == 0) { /* defining players name */
212a8fba37dSchristos if ((i = lgetw()) == 0)
213a8fba37dSchristos break;
2149cc7e274Sdholland strlcpy(logname, i, LOGNAMESIZE);
215a8fba37dSchristos flag = 0;
216a8fba37dSchristos } else if (strcmp(i, "no-introduction") == 0)
217a8fba37dSchristos nowelcome = 1;
218a8fba37dSchristos else if (strcmp(i, "no-beep") == 0)
219a8fba37dSchristos nobeep = 1;
220f5334b08Sdholland else if (strcmp(i, "process-name:") == 0) {
221a8fba37dSchristos if ((i = lgetw()) == 0)
222a8fba37dSchristos break;
2239cc7e274Sdholland strlcpy(psname, i, PSNAMESIZE);
224b6e0b3d3Sdholland } else if (strcmp(i, "play-day-play") == 0) {
225b6e0b3d3Sdholland /* bypass time restrictions: ignored */
226f5334b08Sdholland } else if (strcmp(i, "savefile:") == 0) { /* defining savefilename */
227a8fba37dSchristos if ((i = lgetw()) == 0)
228a8fba37dSchristos break;
229a8fba37dSchristos strcpy(savefilename, i);
230a8fba37dSchristos flag = 0;
23161f28255Scgd }
23261f28255Scgd }
233a8fba37dSchristos if (flag)
234a8fba37dSchristos strcpy(logname, loginname);
23561f28255Scgd }
236