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