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