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