Merge from vendor branch BIND:
[dragonfly.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  * @(#)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 }