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