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