xref: /dragonfly/games/battlestar/fly.c (revision 9bb2a92d)
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  * @(#)fly.c	8.1 (Berkeley) 5/31/93
34  * $FreeBSD: src/games/battlestar/fly.c,v 1.6.2.1 2001/03/05 11:45:36 kris Exp $
35  * $DragonFly: src/games/battlestar/fly.c,v 1.3 2003/11/12 14:53:52 eirikn Exp $
36  */
37 
38 #include "externs.h"
39 #undef UP
40 #include <curses.h>
41 #include <string.h>
42 
43 #define abs(a)	((a) < 0 ? -(a) : (a))
44 #define MIDR  (LINES/2 - 1)
45 #define MIDC  (COLS/2 - 1)
46 
47 int row, column;
48 int dr = 0, dc = 0;
49 char destroyed;
50 int gclock = 120;		/* gtime for all the flights in the game */
51 char cross = 0;
52 sig_t oldsig;
53 
54 static void	blast (void);
55 static void	endfly (void);
56 static void	moveenemy (int);
57 static void	notarget (void);
58 static void	succumb (int);
59 static void	screen (void);
60 static void	target (void);
61 
62 void
63 succumb(sig)
64 	int sig;
65 {
66 
67 	sig = 0;
68 	if (oldsig == SIG_DFL) {
69 		endfly();
70 		exit(1);
71 	}
72 	if (oldsig != SIG_IGN) {
73 		endfly();
74 		(*oldsig)(SIGINT);
75 	}
76 }
77 
78 int
79 visual()
80 {
81 
82 	destroyed = 0;
83 	if(initscr() == NULL){
84 		puts("Whoops!  No more memory...");
85 		return(0);
86 	}
87 	oldsig = signal(SIGINT, succumb);
88 	crmode();
89 	noecho();
90 	screen();
91 	row = rnd(LINES-3) + 1;
92 	column = rnd(COLS-2) + 1;
93 	moveenemy(0);
94 	for (;;) {
95 		switch(getchar()){
96 
97 			case 'h':
98 			case 'r':
99 				dc = -1;
100 				fuel--;
101 				break;
102 
103 			case 'H':
104 			case 'R':
105 				dc = -5;
106 				fuel -= 10;
107 				break;
108 
109 			case 'l':
110 				dc = 1;
111 				fuel--;
112 				break;
113 
114 			case 'L':
115 				dc = 5;
116 				fuel -= 10;
117 				break;
118 
119 			case 'j':
120 			case 'u':
121 				dr = 1;
122 				fuel--;
123 				break;
124 
125 			case 'J':
126 			case 'U':
127 				dr = 5;
128 				fuel -= 10;
129 				break;
130 
131 			case 'k':
132 			case 'd':
133 				dr = -1;
134 				fuel--;
135 				break;
136 
137 			case 'K':
138 			case 'D':
139 				dr = -5;
140 				fuel -= 10;
141 				break;
142 
143 			case '+':
144 				if (cross){
145 					cross = 0;
146 					notarget();
147 				}
148 				else
149 					cross = 1;
150 				break;
151 
152 			case ' ':
153 			case 'f':
154 				if (torps){
155 					torps -= 2;
156 					blast();
157 					if (row == MIDR && column - MIDC < 2 && MIDC - column < 2){
158 						destroyed = 1;
159 						alarm(0);
160 					}
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 (gclock <= 0){
182 			endfly();
183 			die(0);
184 		}
185 	}
186 	/* NOTREACHED */
187 	return(1);
188 }
189 
190 void
191 screen()
192 {
193 	int r,c,n;
194 	int i;
195 
196 	clear();
197 	i = rnd(100);
198 	for (n=0; n < i; n++){
199 		r = rnd(LINES-3) + 1;
200 		c = rnd(COLS);
201 		mvaddch(r, c, '.');
202 	}
203 	mvaddstr(LINES-1-1,21,"TORPEDOES           FUEL           TIME");
204 	refresh();
205 }
206 
207 void
208 target()
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 void
221 notarget()
222 {
223 	int n;
224 
225 	move(MIDR,MIDC-10);
226 	addstr("                     ");
227 	for (n = MIDR-4; n < MIDR-1; n++){
228 		mvaddch(n,MIDC,' ');
229 		mvaddch(n+6,MIDC,' ');
230 	}
231 }
232 
233 void
234 blast()
235 {
236 	int n;
237 
238 	alarm(0);
239 	move(LINES-1, 24);
240 	printw((char *)(uintptr_t)(const void *)"%3d", torps);
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 	mvaddch(MIDR,MIDC,'*');
247 	for(n = LINES-1-2; n >= MIDR + 1; n--){
248 		mvaddch(n, MIDC+MIDR-n, ' ');
249 		mvaddch(n, MIDC-MIDR+n, ' ');
250 		refresh();
251 	}
252 	alarm(1);
253 }
254 
255 void
256 moveenemy(int sig)
257 {
258 	double d;
259 	int oldr, oldc;
260 
261 	sig = 0;
262 	oldr = row;
263 	oldc = column;
264 	if (fuel > 0){
265 		if (row + dr <= LINES-3 && row + dr > 0)
266 			row += dr;
267 		if (column + dc < COLS-1 && column + dc > 0)
268 			column += dc;
269 	} else if (fuel < 0){
270 		fuel = 0;
271 		mvaddstr(0,60,"*** Out of fuel ***");
272 	}
273 	d = (double) ((row - MIDR)*(row - MIDR) + (column - MIDC)*(column - MIDC));
274 	if (d < 16){
275 		row += (rnd(9) - 4) % (4 - abs(row - MIDR));
276 		column += (rnd(9) - 4) % (4 - abs(column - MIDC));
277 	}
278 	gclock--;
279 	mvaddstr(oldr, oldc - 1, "   ");
280 	if (cross)
281 		target();
282 	mvaddstr(row, column - 1, "/-\\");
283 	move(LINES-1, 24);
284 	printw((char *)(uintptr_t)(const void *)"%3d", torps);
285 	move(LINES-1, 42);
286 	printw((char *)(uintptr_t)(const void *)"%3d", fuel);
287 	move(LINES-1, 57);
288 	printw((char *)(uintptr_t)(const void *)"%3d", gclock);
289 	refresh();
290 	signal(SIGALRM, moveenemy);
291 	alarm(1);
292 }
293 
294 void
295 endfly()
296 {
297 	alarm(0);
298 	signal(SIGALRM, SIG_DFL);
299 	mvcur(0,COLS-1,LINES-1,0);
300 	endwin();
301 	signal(SIGTSTP, SIG_DFL);
302 	signal(SIGINT, oldsig);
303 }
304