xref: /netbsd-src/games/larn/tok.c (revision c34afa686bf074a6dcc7f17157faae72111dde9a)
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