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