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 } 402