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