1 /* $OpenBSD: fly.c,v 1.8 2000/09/24 21:55:25 pjanzen Exp $ */ 2 /* $NetBSD: fly.c,v 1.3 1995/03/21 15:07:28 cgd Exp $ */ 3 4 /* 5 * Copyright (c) 1983, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37 #ifndef lint 38 #if 0 39 static char sccsid[] = "@(#)fly.c 8.2 (Berkeley) 4/28/95"; 40 #else 41 static char rcsid[] = "$OpenBSD: fly.c,v 1.8 2000/09/24 21:55:25 pjanzen Exp $"; 42 #endif 43 #endif /* not lint */ 44 45 #include "extern.h" 46 #undef UP 47 #include <curses.h> 48 49 #define MIDR (LINES/2 - 1) 50 #define MIDC (COLS/2 - 1) 51 52 int ourclock = 120; /* time for all the flights in the game */ 53 54 static int row, column; 55 static int dr = 0, dc = 0; 56 static char destroyed; 57 static char cross = 0; 58 static sig_t oldsig; 59 60 static void blast __P((void)); 61 static void endfly __P((void)); 62 static void moveenemy __P((int)); 63 static void notarget __P((void)); 64 static void screen __P((void)); 65 static void succumb __P((int)); 66 static void target __P((void)); 67 68 static void 69 succumb(sigraised) 70 int sigraised; 71 { 72 if (oldsig == SIG_DFL) { 73 endfly(); 74 exit(1); 75 } 76 if (oldsig != SIG_IGN) { 77 endfly(); 78 (*oldsig)(SIGINT); 79 } 80 } 81 82 int 83 visual() 84 { 85 destroyed = 0; 86 if (initscr() == NULL) { 87 puts("Whoops! No more memory..."); 88 return (0); 89 } 90 oldsig = signal(SIGINT, succumb); 91 crmode(); 92 noecho(); 93 screen(); 94 row = rnd(LINES - 3) + 1; 95 column = rnd(COLS - 2) + 1; 96 moveenemy(0); 97 for (;;) { 98 switch (getchar()) { 99 100 case 'h': 101 case 'r': 102 dc = -1; 103 fuel--; 104 break; 105 106 case 'H': 107 case 'R': 108 dc = -5; 109 fuel -= 10; 110 break; 111 112 case 'l': 113 dc = 1; 114 fuel--; 115 break; 116 117 case 'L': 118 dc = 5; 119 fuel -= 10; 120 break; 121 122 case 'j': 123 case 'u': 124 dr = 1; 125 fuel--; 126 break; 127 128 case 'J': 129 case 'U': 130 dr = 5; 131 fuel -= 10; 132 break; 133 134 case 'k': 135 case 'd': 136 dr = -1; 137 fuel--; 138 break; 139 140 case 'K': 141 case 'D': 142 dr = -5; 143 fuel -= 10; 144 break; 145 146 case '+': 147 if (cross) { 148 cross = 0; 149 notarget(); 150 } else 151 cross = 1; 152 break; 153 154 case ' ': 155 case 'f': 156 if (torps) { 157 torps -= 2; 158 blast(); 159 if (row == MIDR && column - MIDC < 2 && MIDC - column < 2) { 160 destroyed = 1; 161 alarm(0); 162 } 163 } else 164 mvaddstr(0, 0, "*** Out of torpedoes. ***"); 165 break; 166 167 case 'q': 168 endfly(); 169 return (0); 170 171 default: 172 mvaddstr(0, 26, "Commands = r,R,l,L,u,U,d,D,f,+,q"); 173 continue; 174 175 case EOF: 176 break; 177 } 178 if (destroyed) { 179 endfly(); 180 return (1); 181 } 182 if (ourclock <= 0) { 183 endfly(); 184 die(0); 185 } 186 } 187 } 188 189 static void 190 screen() 191 { 192 int r, c, n; 193 int i; 194 195 clear(); 196 i = rnd(100); 197 for (n = 0; n < i; n++) { 198 r = rnd(LINES - 3) + 1; 199 c = rnd(COLS); 200 mvaddch(r, c, '.'); 201 } 202 mvaddstr(LINES - 1 - 1, 21, "TORPEDOES FUEL TIME"); 203 refresh(); 204 } 205 206 static void 207 target() 208 { 209 int n; 210 211 move(MIDR, MIDC - 10); 212 addstr("------- + -------"); 213 for (n = MIDR - 4; n < MIDR - 1; n++) { 214 mvaddch(n, MIDC, '|'); 215 mvaddch(n + 6, MIDC, '|'); 216 } 217 } 218 219 static void 220 notarget() 221 { 222 int n; 223 224 move(MIDR, MIDC - 10); 225 addstr(" "); 226 for (n = MIDR - 4; n < MIDR - 1; n++) { 227 mvaddch(n, MIDC, ' '); 228 mvaddch(n + 6, MIDC, ' '); 229 } 230 } 231 232 static void 233 blast() 234 { 235 int n; 236 237 alarm(0); 238 move(LINES - 1, 24); 239 printw("%3d", torps); 240 for(n = LINES - 1 - 2; n >= MIDR + 1; n--) { 241 mvaddch(n, MIDC + MIDR - n, '/'); 242 mvaddch(n, MIDC - MIDR + n, '\\'); 243 refresh(); 244 } 245 mvaddch(MIDR, MIDC, '*'); 246 for (n = LINES - 1 - 2; n >= MIDR + 1; n--) { 247 mvaddch(n, MIDC + MIDR - n, ' '); 248 mvaddch(n, MIDC - MIDR + n, ' '); 249 refresh(); 250 } 251 alarm(1); 252 } 253 254 static void 255 moveenemy(sigraised) 256 int sigraised; 257 { 258 double d; 259 int oldr, oldc; 260 261 oldr = row; 262 oldc = column; 263 if (fuel > 0) { 264 if (row + dr <= LINES - 3 && row + dr > 0) 265 row += dr; 266 if (column + dc < COLS - 1 && column + dc > 0) 267 column += dc; 268 } else 269 if (fuel < 0) { 270 fuel = 0; 271 mvaddstr(0, 60, "*** Out of fuel ***"); 272 } 273 d = (double) ((row - MIDR) * (row - MIDR) + (column - MIDC) * (column - MIDC)); 274 if (d < 16) { 275 row += (rnd(9) - 4) % (4 - abs(row - MIDR)); 276 column += (rnd(9) - 4) % (4 - abs(column - MIDC)); 277 } 278 ourclock--; 279 mvaddstr(oldr, oldc - 1, " "); 280 if (cross) 281 target(); 282 mvaddstr(row, column - 1, "/-\\"); 283 move(LINES - 1, 24); 284 printw("%3d", torps); 285 move(LINES - 1, 42); 286 printw("%3d", fuel); 287 move(LINES - 1, 57); 288 printw("%3d", ourclock); 289 refresh(); 290 signal(SIGALRM, moveenemy); 291 alarm(1); 292 } 293 294 static void 295 endfly() 296 { 297 alarm(0); 298 signal(SIGALRM, SIG_DFL); 299 mvcur(0, COLS - 1, LINES - 1, 0); 300 endwin(); 301 setvbuf(stdout, NULL, _IOLBF, BUFSIZ); 302 signal(SIGTSTP, SIG_DFL); 303 signal(SIGINT, oldsig); 304 } 305