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