xref: /netbsd-src/games/larn/tok.c (revision c34afa686bf074a6dcc7f17157faae72111dde9a)
1 /*	$NetBSD: tok.c,v 1.11 2012/06/19 05:30:44 dholland Exp $	*/
2 
3 /* tok.c		Larn is copyrighted 1986 by Noah Morgan. */
4 #include <sys/cdefs.h>
5 #ifndef lint
6 __RCSID("$NetBSD: tok.c,v 1.11 2012/06/19 05:30:44 dholland Exp $");
7 #endif				/* not lint */
8 
9 #include <sys/types.h>
10 #include <string.h>
11 #include <sys/ioctl.h>
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <sys/wait.h>
15 #include <ctype.h>
16 #include "header.h"
17 #include "extern.h"
18 
19 /* Keystrokes (roughly) between checkpoints */
20 #define CHECKPOINT_INTERVAL	400
21 
22 static char     lastok = 0;
23 int             yrepcount = 0;
24 #ifndef FLUSHNO
25 #define FLUSHNO 5
26 #endif	/* FLUSHNO */
27 static int      flushno = FLUSHNO;	/* input queue flushing threshold */
28 #define MAXUM 52		/* maximum number of user re-named monsters */
29 #define MAXMNAME 40		/* max length of a monster re-name */
30 static char     usermonster[MAXUM][MAXMNAME];	/* the user named monster
31 						 * name goes here */
32 static u_char     usermpoint = 0;	/* the user monster pointer */
33 
34 /*
35 	lexical analyzer for larn
36  */
37 int
yylex(void)38 yylex(void)
39 {
40 	char            cc;
41 	int             ic;
42 	if (hit2flag) {
43 		hit2flag = 0;
44 		yrepcount = 0;
45 		return (' ');
46 	}
47 	if (yrepcount > 0) {
48 		--yrepcount;
49 		return (lastok);
50 	} else
51 		yrepcount = 0;
52 	if (yrepcount == 0) {
53 		bottomdo();
54 		showplayer();
55 	}			/* show where the player is	 */
56 	lflush();
57 	while (1) {
58 		c[BYTESIN]++;
59 		/* check for periodic checkpointing */
60 		if (ckpflag)
61 			if ((c[BYTESIN] % CHECKPOINT_INTERVAL) == 0) {
62 #ifndef DOCHECKPOINTS
63 				savegame(ckpfile);
64 #else
65 				wait(0);	/* wait for other forks to
66 						 * finish */
67 				if (fork() == 0) {
68 					savegame(ckpfile);
69 					exit();
70 				}
71 #endif
72 			}
73 		do {		/* if keyboard input buffer is too big, flush
74 				 * some of it */
75 			ioctl(0, FIONREAD, &ic);
76 			if (ic > flushno)
77 				read(0, &cc, 1);
78 		}
79 		while (ic > flushno);
80 
81 		if (read(0, &cc, 1) != 1)
82 			return (lastok = -1);
83 
84 		if (cc == 'Y' - 64) {	/* control Y -- shell escape */
85 			resetscroll();
86 			clear();/* scrolling region, home, clear, no
87 				 * attributes */
88 			if ((ic = fork()) == 0) {	/* child */
89 				execl("/bin/csh", "/bin/csh", NULL);
90 				exit(1);
91 			}
92 			wait(0);
93 			if (ic < 0) {	/* error */
94 				write(2, "Can't fork off a shell!\n", 25);
95 				sleep(2);
96 			}
97 			setscroll();
98 			return (lastok = 'L' - 64);	/* redisplay screen */
99 		}
100 		if ((cc <= '9') && (cc >= '0')) {
101 			yrepcount = yrepcount * 10 + cc - '0';
102 		} else {
103 			if (yrepcount > 0)
104 				--yrepcount;
105 			return (lastok = cc);
106 		}
107 	}
108 }
109 
110 /*
111  *	flushall()		Function to flush all type-ahead in the input buffer
112  */
113 void
flushall(void)114 flushall(void)
115 {
116 	char            cc;
117 	int             ic;
118 	for (;;) {		/* if keyboard input buffer is too big, flush
119 				 * some of it */
120 		ioctl(0, FIONREAD, &ic);
121 		if (ic <= 0)
122 			return;
123 		while (ic > 0) {
124 			read(0, &cc, 1);
125 			--ic;
126 		}		/* gobble up the byte */
127 	}
128 }
129 
130 /*
131 	function to set the desired hardness
132 	enter with hard= -1 for default hardness, else any desired hardness
133  */
134 void
sethard(int hard)135 sethard(int hard)
136 {
137 	int    j, k, i;
138 	struct monst *mp;
139 
140 	j = c[HARDGAME];
141 	hashewon();
142 	if (restorflag == 0) {	/* don't set c[HARDGAME] if restoring game */
143 		if (hard >= 0)
144 			c[HARDGAME] = hard;
145 	} else
146 		c[HARDGAME] = j;/* set c[HARDGAME] to proper value if
147 				 * restoring game */
148 
149 	if ((k = c[HARDGAME]) != 0)
150 		for (j = 0; j <= MAXMONST + 8; j++) {
151 			mp = &monster[j];
152 			i = ((6 + k) * mp->hitpoints + 1) / 6;
153 			mp->hitpoints = (i < 0) ? 32767 : i;
154 			i = ((6 + k) * mp->damage + 1) / 5;
155 			mp->damage = (i > 127) ? 127 : i;
156 			i = (10 * mp->gold) / (10 + k);
157 			mp->gold = (i > 32767) ? 32767 : i;
158 			i = mp->armorclass - k;
159 			mp->armorclass = (i < -127) ? -127 : i;
160 			i = (7 * mp->experience) / (7 + k) + 1;
161 			mp->experience = (i <= 0) ? 1 : i;
162 		}
163 }
164 
165 /*
166 	function to read and process the larn options file
167  */
168 void
readopts(void)169 readopts(void)
170 {
171 	const char  *i;
172 	int    j, k;
173 	int             flag;
174 
175 	flag = 1;		/* set to 0 if a name is specified */
176 
177 	if (lopen(optsfile) < 0) {
178 		strcpy(logname, loginname);
179 		return;		/* user name if no character name */
180 	}
181 	i = " ";
182 	while (*i) {
183 		if ((i = lgetw()) == NULL)
184 			break;	/* check for EOF */
185 		while ((*i == ' ') || (*i == '\t'))
186 			i++;	/* eat leading whitespace */
187 
188 		if (strcmp(i, "bold-objects") == 0)
189 			boldon = 1;
190 		else if (strcmp(i, "enable-checkpointing") == 0)
191 			ckpflag = 1;
192 		else if (strcmp(i, "inverse-objects") == 0)
193 			boldon = 0;
194 		else if (strcmp(i, "female") == 0)
195 			sex = 0;	/* male or female */
196 		else if (strcmp(i, "monster:") == 0) {	/* name favorite monster */
197 			if ((i = lgetw()) == 0)
198 				break;
199 			strlcpy(usermonster[usermpoint], i, MAXMNAME);
200 			if (usermpoint >= MAXUM)
201 				continue;	/* defined all of em */
202 			if (isalpha(j = usermonster[usermpoint][0])) {
203 				for (k = 1; k < MAXMONST + 8; k++)	/* find monster */
204 					if (monstnamelist[k] == j) {
205 						monster[k].name = &usermonster[usermpoint++][0];
206 						break;
207 					}
208 			}
209 		} else if (strcmp(i, "male") == 0)
210 			sex = 1;
211 		else if (strcmp(i, "name:") == 0) {	/* defining players name */
212 			if ((i = lgetw()) == 0)
213 				break;
214 			strlcpy(logname, i, LOGNAMESIZE);
215 			flag = 0;
216 		} else if (strcmp(i, "no-introduction") == 0)
217 			nowelcome = 1;
218 		else if (strcmp(i, "no-beep") == 0)
219 			nobeep = 1;
220 		else if (strcmp(i, "process-name:") == 0) {
221 			if ((i = lgetw()) == 0)
222 				break;
223 			strlcpy(psname, i, PSNAMESIZE);
224 		} else if (strcmp(i, "play-day-play") == 0) {
225 			/* bypass time restrictions: ignored */
226 		} else if (strcmp(i, "savefile:") == 0) {	/* defining savefilename */
227 			if ((i = lgetw()) == 0)
228 				break;
229 			strcpy(savefilename, i);
230 			flag = 0;
231 		}
232 	}
233 	if (flag)
234 		strcpy(logname, loginname);
235 }
236