]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - warp/warp.c
Add testpat(6) to games.
[bsdgames-darwin.git] / warp / warp.c
1 char rcsid[] = "@(#)Header: warp.c,v 7.0.1.3 86/12/12 17:07:44 lwall Exp";
2
3 /* warp -- a real-time space war program
4 * author: Larry Wall
5 * helpers: Jonathan and Mark Biggar, and Dan Faigin
6 * special thanks to my sweetie Gloria who suggested the Planet Crusher
7 *
8 * Copyright (c) 2020 The NetBSD Foundation, Inc.
9 * All rights reserved.
10 *
11 * This code is derived from software contributed to The NetBSD Foundation
12 * by Larry Wall.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
27 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 *
35 * version 5.0 04/20/83
36 * 5.1 05/05/83 various tidbits
37 * 5.2 05/12/83 VAX -> vax, ifdef'ed a SIGCONT
38 * 5.3 05/24/83 RCS
39 *
40 * Log: warp.c,v
41 * Revision 7.0.1.3 86/12/12 17:07:44 lwall
42 * Baseline for net release.
43 *
44 * Revision 7.0.1.2 86/10/20 12:08:00 lwall
45 * Made all exits reset tty.
46 *
47 * Revision 7.0.1.1 86/10/16 10:54:13 lwall
48 * Added Damage. Fixed random bugs.
49 *
50 * Revision 7.0 86/10/08 15:14:47 lwall
51 * Split into separate files. Added amoebas and pirates.
52 *
53 * Revision 6.4 83/12/16 13:11:45 lwall
54 * Handled 15 bit random number generators.
55 *
56 * Fixed array overflow bug on multiple zaps.
57 *
58 * Multiple zaps now consolidated to minimize output.
59 *
60 * Tholian jackpot games outlawed under difficulty 15.
61 *
62 * Revision 6.3 83/08/24 11:17:49 lwall
63 * Fixed array overflow bug on multiple zap.
64 *
65 * Revision 6.2 83/08/23 18:06:37 lwall
66 * Added zap command.
67 * Warp -s should now work on dumb terminals
68 * Specifying difficulty >= 40 now just makes it a special game.
69 * SIGTTOU #ifdef'ed.
70 * No-delay read provided as alternative to FIONREAD.
71 * Warp won't report "-1 obsolete" when there are no Enterprises left.
72 * Some high-difficulty tuning.
73 *
74 * Revision 6.1 83/08/17 08:49:03 lwall
75 * Fixed obscure bug in storing UP that caused a %. in CM to occasionally
76 * foist garbage onto the screen.
77 *
78 * Revision 6.0 83/08/08 17:09:26 lwall
79 * New baseline version for net release.
80 *
81 * Revision 5.5 83/08/01 10:59:56 lwall
82 * Cloaking for the Enterprise.
83 * Difficulty now goes to 99, and many activities depending on difficulty
84 * have been adjusted in frequency.
85 * Simplified exit sequence, and reduced dependencies on control
86 * characters. You needn't see the scoreboard if you don't want to.
87 * Hitting i,w,c, or v switches to Enterprise. Hitting p switches to Base.
88 * Excessive use of q is not allowed.
89 * Excessive use of D is not allowed.
90 * Scoreboard may depend on either full name or login name.
91 * Integrated scoreboard lister. Login name now shows up on scoreboard.
92 * "Hidden" startup options are now upper case.
93 * Checks upon startup for no cursor movement, or screen too small.
94 * Checks upon startup that WARPDIR is correctly protected, and that warp
95 * is running setuid. As an additional bonus this prevents root from
96 * running warp, which mucks things up, UN*X be blessed.
97 * All gets's turned into fgets's for safety.
98 * Bonus Enterprises and Bases.
99 * Escalating bonuses for saving Base and Enterprise.
100 * Escalating Enterprise energy.
101 * Turbolasers decrease with distance.
102 * Really smart enemies can see through stars occasionally.
103 * Occasional Tholian jackpot waves. Tholians are a trifle nastier.
104 * Choleric Gorns.
105 * An O or o can miss seeing you. Enemies can avoid a stationary O, o, or X.
106 * Warp 3 enemies and other nastinesses are possible in massacre mode.
107 * Enemies that decide to navigate when they see you can do other things than
108 * just come toward you.
109 * Gorns occasionally launch a salvo for the fun of it.
110 * Only star and enemy explosions can keep the round going now.
111 * Bounces don't always go back to starting spot now.
112 * Better full name processing. USG quirks handled. & substitution also
113 * handled now (whoever dreamed up that one must have been in the middle
114 * of the night before the morning after).
115 * Catch ^D on fgets.
116 * Version number printer.
117 * Less signal catching during debugging.
118 *
119 * Revision 5.4 83/06/24 09:28:38 lwall
120 * 16 bit random number generators are now supported.
121 * Made warp not blow up on a null save file.
122 * Warp now prints E and B before the stars.
123 * Fixed bug which caused torp count to get decremented even when no torp
124 * was launched because of an obstacle.
125 * Put %<n>ld formats where appropriate.
126 * Fixed E: 0 0 bug on refresh.
127 *
128 * Revision 5.3 83/05/24 14:03:10 lwall
129 * Starting RCS
130 *
131 */
132
133 #include "INTERN.h"
134 #include "warp.h"
135 #include "EXTERN.h"
136 #include "bang.h"
137 #include "init.h"
138 #include "intrp.h"
139 #include "object.h"
140 #include "move.h"
141 #include "play.h"
142 #include "score.h"
143 #include "sig.h"
144 #include "term.h"
145 #include "them.h"
146 #include "us.h"
147 #include "util.h"
148 #include "version.h"
149 #include "weapon.h"
150
151 int
152 main(int argc, char *argv[])
153 {
154 char tmp, *s, *tcbuf;
155
156 FILE *savfil;
157
158 #ifdef lint /* to suppress "defined but never used" */
159 # ifdef SIGTSTP
160 (void)stop_catcher();
161 # endif
162 # ifdef SIGCONT
163 (void)cont_catcher();
164 # endif
165 #endif
166
167 while (--argc > 0 && (*++argv)[0] == '-')
168 for (s = argv[0]+1; *s != '\0'; s++)
169 switch (*s) {
170 case '&':
171 amoebaspec = true;
172 beginner = true;
173 break;
174 case 'A':
175 apolspec = true;
176 beginner = true;
177 break;
178 case 'b':
179 beginner = true;
180 break;
181 case 'C':
182 crushspec = true;
183 beginner = true;
184 break;
185 case 'D':
186 debugging = true;
187 #ifdef DEBUGGING
188 debug = atoi(++s);
189 #endif
190 s += strlen(s)-1;
191 break;
192 case 'd':
193 s++;
194 if (*s == '=') s++;
195 ismarts = atoi(s);
196 if (ismarts <= 0)
197 ismarts = 1;
198 if (ismarts > 99)
199 ismarts = 99;
200 if (ismarts > 40)
201 beginner = true;
202 s += strlen(s)-1;
203 break;
204 case 'E':
205 klingspec = true;
206 beginner = true;
207 s++;
208 if (*s == '=') s++;
209 inumenemies = atoi(s);
210 s += strlen(s)-1;
211 break;
212 case 'F':
213 friendspec = true;
214 beginner = true;
215 s++;
216 if (*s == '=') s++;
217 inumfriends = atoi(s);
218 s += strlen(s)-1;
219 break;
220 case 'G':
221 gornspec = true;
222 beginner = true;
223 break;
224 case 'l':
225 lowspeed = true;
226 break;
227 case 'm':
228 metakey = true;
229 break;
230 case 'M':
231 massacre = true;
232 break;
233 case 'P':
234 piratespec = true;
235 beginner = true;
236 s++;
237 if (*s == '=') s++;
238 inumpirates = atoi(s);
239 s += strlen(s)-1;
240 break;
241 case 'S':
242 prespec = true;
243 beginner = true;
244 s++;
245 if (*s == '=') s++;
246 if (*s)
247 prescene = atoi(s);
248 else
249 prescene = -1;
250 s += strlen(s)-1;
251 break;
252 case 'R':
253 romspec = true;
254 beginner = true;
255 break;
256 case '*':
257 starspec = true;
258 beginner = true;
259 s++;
260 if (*s == '=') s++;
261 inumstars = atoi(s);
262 s += strlen(s)-1;
263 break;
264 case 's':
265 scorespec = true;
266 break;
267 case 'T':
268 tholspec = true;
269 beginner = true;
270 break;
271 case 'x':
272 experimenting = true;
273 break;
274 case 'v':
275 version();
276 exit(0);
277 break;
278 default:
279 fprintf(stderr,"warp: illegal option %c\n", *s);
280 fprintf(stderr, "Usage: warp -dn -b -x -v -s\n");
281 exit(1);
282 }
283 if (argc != 0) {
284 fprintf(stderr, "Usage: warp -dn -b -x -v -s\n");
285 exit(1);
286 }
287 bang_init();
288 move_init();
289 object_init();
290 play_init();
291 them_init();
292 us_init();
293 util_init();
294 weapon_init();
295
296 tcbuf = malloc(1024);
297 intrp_init(tcbuf);
298
299 if (chdir(warplib) < 0)
300 fprintf(stderr,NOCD,warplib);
301
302 term_init();
303
304 term_set(tcbuf);
305 free(tcbuf);
306
307 umask(022); /* mustn't rely on incoming umask--could be 033 which */
308 /* would disable people from running wscore */
309
310 score_init();
311
312 sig_init();
313
314 if (totalscore) {
315 clear();
316 mvaddstr(12,25,"*** restoring saved game ***");
317 roundsleep(1);
318 }
319
320 srandom(getpid());
321
322 do {
323 for (keepgoing = true;;) {
324 if (!experimenting) {
325 if ((savfil = fopen(savefilename,"w")) == NULL) {
326 resetty();
327 printf("Can't open savefile `%s'\r\n", savefilename);
328 finalize(1);
329 }
330 fprintf(savfil,
331 "%-8s %10ld, %2d,%5d,%2d,%2d,%3d %c%c%c%c%c%c%c%c%c\n",
332 logname, totalscore, smarts, cumsmarts,
333 numents, numbases, wave,
334 apolspec ? 'a' : ' ',
335 beginner ? 'b' : ' ',
336 crushspec ? 'c' : ' ',
337 gornspec ? 'g' : ' ',
338 massacre ? 'm' : ' ',
339 romspec ? 'r' : ' ',
340 tholspec ? 't' : ' ',
341 lowspeed ? 'l' : ' ',
342 amoebaspec ? '&' : ' '
343 );
344 fprintf(savfil," running on %s, process #%d\n",
345 term+5,getpid());
346 fclose(savfil);
347 }
348
349 lastscore = totalscore;
350 initialize();
351 play();
352 cumsmarts += smarts;
353 wavescore();
354 if (numents<=0 && numbases<=0)
355 keepgoing = false;
356 if (!keepgoing) break;
357 do {
358 if (experimenting) {
359 mvaddstr(23,15,
360 " [Hit space to continue, 'q' to quit] ");
361 }
362 else {
363 mvaddstr(23,15,
364 "[Hit space to continue, 's' to save, 'q' to quit]");
365 }
366 sleep(1);
367 fflush(stdout);
368 eat_typeahead();
369 getcmd(&tmp);
370 if (tmp == BREAKCH || tmp == INTRCH) {
371 mvaddstr(23,15,
372 " ");
373 mvaddstr(23,33,
374 "Really quit? ");
375 getcmd(&tmp);
376 if (tmp == 'y' || tmp == 'Y')
377 tmp = 'q';
378 else
379 tmp = 1;
380 }
381 } while (tmp != INTRCH && tmp != BREAKCH && !strchr(" qQs",tmp));
382 if (tmp != ' ' && tmp != 's') break;
383 if (!beginner && smarts < 20)
384 smarts += 4;
385 else if (!beginner && smarts < 35)
386 smarts += 2;
387 else if (smarts < 99)
388 smarts++;
389 if (tmp == 's') save_game();
390 }
391 score();
392
393 } while (justonemoretime);
394
395 if (!experimenting)
396 unlink(savefilename);
397
398 clear();
399 resetty();
400 exit(0);
401 }