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