Initial import from FreeBSD RELENG_4:
[games.git] / games / battlestar / fly.c
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 }