xref: /netbsd/games/larn/tok.c (revision bf9ec67e)
1 /*	$NetBSD: tok.c,v 1.5 1997/10/18 20:03:54 christos 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.5 1997/10/18 20:03:54 christos 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 "header.h"
16 #include "extern.h"
17 
18 static char     lastok = 0;
19 int             yrepcount = 0, dayplay = 0;
20 #ifndef FLUSHNO
21 #define FLUSHNO 5
22 #endif	/* FLUSHNO */
23 static int      flushno = FLUSHNO;	/* input queue flushing threshold */
24 #define MAXUM 52		/* maximum number of user re-named monsters */
25 #define MAXMNAME 40		/* max length of a monster re-name */
26 static char     usermonster[MAXUM][MAXMNAME];	/* the user named monster
27 						 * name goes here */
28 static u_char     usermpoint = 0;	/* the user monster pointer */
29 
30 /*
31 	lexical analyzer for larn
32  */
33 int
34 yylex()
35 {
36 	char            cc;
37 	int             ic;
38 	if (hit2flag) {
39 		hit2flag = 0;
40 		yrepcount = 0;
41 		return (' ');
42 	}
43 	if (yrepcount > 0) {
44 		--yrepcount;
45 		return (lastok);
46 	} else
47 		yrepcount = 0;
48 	if (yrepcount == 0) {
49 		bottomdo();
50 		showplayer();
51 	}			/* show where the player is	 */
52 	lflush();
53 	while (1) {
54 		c[BYTESIN]++;
55 		if (ckpflag)
56 			if ((c[BYTESIN] % 400) == 0) {	/* check for periodic
57 							 * checkpointing */
58 #ifndef DOCHECKPOINTS
59 				savegame(ckpfile);
60 #else
61 				wait(0);	/* wait for other forks to
62 						 * finish */
63 				if (fork() == 0) {
64 					savegame(ckpfile);
65 					exit();
66 				}
67 #endif
68 
69 
70 #ifdef TIMECHECK
71 				if (dayplay == 0)
72 					if (playable()) {
73 						cursor(1, 19);
74 						lprcat("\nSorry, but it is now time for work.  Your game has been saved.\n");
75 						beep();
76 						lflush();
77 						savegame(savefilename);
78 						wizard = nomove = 1;
79 						sleep(4);
80 						died(-257);
81 					}
82 #endif	/* TIMECHECK */
83 
84 			}
85 		do {		/* if keyboard input buffer is too big, flush
86 				 * some of it */
87 			ioctl(0, FIONREAD, &ic);
88 			if (ic > flushno)
89 				read(0, &cc, 1);
90 		}
91 		while (ic > flushno);
92 
93 		if (read(0, &cc, 1) != 1)
94 			return (lastok = -1);
95 
96 		if (cc == 'Y' - 64) {	/* control Y -- shell escape */
97 			resetscroll();
98 			clear();/* scrolling region, home, clear, no
99 				 * attributes */
100 			if ((ic = fork()) == 0) {	/* child */
101 				execl("/bin/csh", 0);
102 				exit(1);
103 			}
104 			wait(0);
105 			if (ic < 0) {	/* error */
106 				write(2, "Can't fork off a shell!\n", 25);
107 				sleep(2);
108 			}
109 			setscroll();
110 			return (lastok = 'L' - 64);	/* redisplay screen */
111 		}
112 		if ((cc <= '9') && (cc >= '0')) {
113 			yrepcount = yrepcount * 10 + cc - '0';
114 		} else {
115 			if (yrepcount > 0)
116 				--yrepcount;
117 			return (lastok = cc);
118 		}
119 	}
120 }
121 
122 /*
123  *	flushall()		Function to flush all type-ahead in the input buffer
124  */
125 void
126 flushall()
127 {
128 	char            cc;
129 	int             ic;
130 	for (;;) {		/* if keyboard input buffer is too big, flush
131 				 * some of it */
132 		ioctl(0, FIONREAD, &ic);
133 		if (ic <= 0)
134 			return;
135 		while (ic > 0) {
136 			read(0, &cc, 1);
137 			--ic;
138 		}		/* gobble up the byte */
139 	}
140 }
141 
142 /*
143 	function to set the desired hardness
144 	enter with hard= -1 for default hardness, else any desired hardness
145  */
146 void
147 sethard(hard)
148 	int             hard;
149 {
150 	int    j, k, i;
151 	j = c[HARDGAME];
152 	hashewon();
153 	if (restorflag == 0) {	/* don't set c[HARDGAME] if restoring game */
154 		if (hard >= 0)
155 			c[HARDGAME] = hard;
156 	} else
157 		c[HARDGAME] = j;/* set c[HARDGAME] to proper value if
158 				 * restoring game */
159 
160 	if ((k = c[HARDGAME]) != 0)
161 		for (j = 0; j <= MAXMONST + 8; j++) {
162 			i = ((6 + k) * monster[j].hitpoints + 1) / 6;
163 			monster[j].hitpoints = (i < 0) ? 32767 : i;
164 			i = ((6 + k) * monster[j].damage + 1) / 5;
165 			monster[j].damage = (i > 127) ? 127 : i;
166 			i = (10 * monster[j].gold) / (10 + k);
167 			monster[j].gold = (i > 32767) ? 32767 : i;
168 			i = monster[j].armorclass - k;
169 			monster[j].armorclass = (i < -127) ? -127 : i;
170 			i = (7 * monster[j].experience) / (7 + k) + 1;
171 			monster[j].experience = (i <= 0) ? 1 : i;
172 		}
173 }
174 
175 /*
176 	function to read and process the larn options file
177  */
178 void
179 readopts()
180 {
181 	char  *i;
182 	int    j, k;
183 	int             flag;
184 	flag = 1;		/* set to 0 if he specifies a name for his
185 				 * character */
186 	if (lopen(optsfile) < 0) {
187 		strcpy(logname, loginname);
188 		return;		/* user name if no character name */
189 	}
190 	i = " ";
191 	while (*i) {
192 		if ((i = (char *) lgetw()) == 0)
193 			break;	/* check for EOF */
194 		while ((*i == ' ') || (*i == '\t'))
195 			i++;	/* eat leading whitespace */
196 		switch (*i) {
197 		case 'b':
198 			if (strcmp(i, "bold-objects") == 0)
199 				boldon = 1;
200 			break;
201 
202 		case 'e':
203 			if (strcmp(i, "enable-checkpointing") == 0)
204 				ckpflag = 1;
205 			break;
206 
207 		case 'i':
208 			if (strcmp(i, "inverse-objects") == 0)
209 				boldon = 0;
210 			break;
211 
212 		case 'f':
213 			if (strcmp(i, "female") == 0)
214 				sex = 0;	/* male or female */
215 			break;
216 
217 		case 'm':
218 			if (strcmp(i, "monster:") == 0) {	/* name favorite monster */
219 				if ((i = lgetw()) == 0)
220 					break;
221 				if (strlen(i) >= MAXMNAME)
222 					i[MAXMNAME - 1] = 0;
223 				strcpy(usermonster[usermpoint], i);
224 				if (usermpoint >= MAXUM)
225 					break;	/* defined all of em */
226 				if (isalpha(j = usermonster[usermpoint][0])) {
227 					for (k = 1; k < MAXMONST + 8; k++)	/* find monster */
228 						if (monstnamelist[k] == j) {
229 							monster[k].name = &usermonster[usermpoint++][0];
230 							break;
231 						}
232 				}
233 			} else if (strcmp(i, "male") == 0)
234 				sex = 1;
235 			break;
236 
237 		case 'n':
238 			if (strcmp(i, "name:") == 0) {	/* defining players name */
239 				if ((i = lgetw()) == 0)
240 					break;
241 				if (strlen(i) >= LOGNAMESIZE)
242 					i[LOGNAMESIZE - 1] = 0;
243 				strcpy(logname, i);
244 				flag = 0;
245 			} else if (strcmp(i, "no-introduction") == 0)
246 				nowelcome = 1;
247 			else if (strcmp(i, "no-beep") == 0)
248 				nobeep = 1;
249 			break;
250 
251 		case 'p':
252 			if (strcmp(i, "process-name:") == 0) {
253 				if ((i = lgetw()) == 0)
254 					break;
255 				if (strlen(i) >= PSNAMESIZE)
256 					i[PSNAMESIZE - 1] = 0;
257 				strcpy(psname, i);
258 			} else if (strcmp(i, "play-day-play") == 0)
259 				dayplay = 1;
260 			break;
261 
262 		case 's':
263 			if (strcmp(i, "savefile:") == 0) {	/* defining savefilename */
264 				if ((i = lgetw()) == 0)
265 					break;
266 				strcpy(savefilename, i);
267 				flag = 0;
268 			}
269 			break;
270 		};
271 	}
272 	if (flag)
273 		strcpy(logname, loginname);
274 }
275