Initial import from FreeBSD RELENG_4:
[games.git] / games / atc / graphics.c
1 /*-
2  * Copyright (c) 1990, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Ed James.
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. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by the University of
19  *      California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36
37 /*
38  * Copyright (c) 1987 by Ed James, UC Berkeley.  All rights reserved.
39  *
40  * Copy permission is hereby granted provided that this notice is
41  * retained on all partial or complete copies.
42  *
43  * For more info on this and all of my stuff, mail edjames@berkeley.edu.
44  */
45
46 #ifndef lint
47 #if 0
48 static char sccsid[] = "@(#)graphics.c  8.1 (Berkeley) 5/31/93";
49 #endif
50 static const char rcsid[] =
51  "$FreeBSD: src/games/atc/graphics.c,v 1.7 1999/11/30 03:48:19 billf Exp $";
52 #endif /* not lint */
53
54 #include <string.h>
55 #include "include.h"
56 #ifdef SYSV
57 #include <errno.h>
58 #endif
59
60 #define C_TOPBOTTOM             '-'
61 #define C_LEFTRIGHT             '|'
62 #define C_AIRPORT               '='
63 #define C_LINE                  '+'
64 #define C_BACKROUND             '.'
65 #define C_BEACON                '*'
66 #define C_CREDIT                '*'
67
68 WINDOW  *radar, *cleanradar, *credit, *input, *planes;
69
70 getAChar()
71 {
72 #ifdef BSD
73         return (getchar());
74 #endif
75 #ifdef SYSV
76         int c;
77
78         while ((c = getchar()) == -1 && errno == EINTR) ;
79         return(c);
80 #endif
81 }
82
83 erase_all()
84 {
85         PLANE   *pp;
86
87         for (pp = air.head; pp != NULL; pp = pp->next) {
88                 wmove(cleanradar, pp->ypos, pp->xpos * 2);
89                 wmove(radar, pp->ypos, pp->xpos * 2);
90                 waddch(radar, winch(cleanradar));
91                 wmove(cleanradar, pp->ypos, pp->xpos * 2 + 1);
92                 wmove(radar, pp->ypos, pp->xpos * 2 + 1);
93                 waddch(radar, winch(cleanradar));
94         }
95 }
96
97 draw_all()
98 {
99         PLANE   *pp;
100
101         for (pp = air.head; pp != NULL; pp = pp->next) {
102                 if (pp->status == S_MARKED)
103                         wstandout(radar);
104                 wmove(radar, pp->ypos, pp->xpos * 2);
105                 waddch(radar, name(pp));
106                 waddch(radar, '0' + pp->altitude);
107                 if (pp->status == S_MARKED)
108                         wstandend(radar);
109         }
110         wrefresh(radar);
111         planewin();
112         wrefresh(input);                /* return cursor */
113         fflush(stdout);
114 }
115
116 init_gr()
117 {
118         static char     buffer[BUFSIZ];
119
120         initscr();
121         setbuf(stdout, buffer);
122         input = newwin(INPUT_LINES, COLS - PLANE_COLS, LINES - INPUT_LINES, 0);
123         credit = newwin(INPUT_LINES, PLANE_COLS, LINES - INPUT_LINES,
124                 COLS - PLANE_COLS);
125         planes = newwin(LINES - INPUT_LINES, PLANE_COLS, 0, COLS - PLANE_COLS);
126 }
127
128 setup_screen(scp)
129         const C_SCREEN  *scp;
130 {
131         int             i, j;
132         char            str[3];
133         const char      *airstr;
134
135         str[2] = '\0';
136
137         if (radar != NULL)
138                 delwin(radar);
139         radar = newwin(scp->height, scp->width * 2, 0, 0);
140
141         if (cleanradar != NULL)
142                 delwin(cleanradar);
143         cleanradar = newwin(scp->height, scp->width * 2, 0, 0);
144
145         /* minus one here to prevent a scroll */
146         for (i = 0; i < PLANE_COLS - 1; i++) {
147                 wmove(credit, 0, i);
148                 waddch(credit, C_CREDIT);
149                 wmove(credit, INPUT_LINES - 1, i);
150                 waddch(credit, C_CREDIT);
151         }
152         wmove(credit, INPUT_LINES / 2, 1);
153         waddstr(credit, AUTHOR_STR);
154
155         for (i = 1; i < scp->height - 1; i++) {
156                 for (j = 1; j < scp->width - 1; j++) {
157                         wmove(radar, i, j * 2);
158                         waddch(radar, C_BACKROUND);
159                 }
160         }
161
162         /*
163          * Draw the lines first, since people like to draw lines
164          * through beacons and exit points.
165          */
166         str[0] = C_LINE;
167         for (i = 0; i < scp->num_lines; i++) {
168                 str[1] = ' ';
169                 draw_line(radar, scp->line[i].p1.x, scp->line[i].p1.y,
170                         scp->line[i].p2.x, scp->line[i].p2.y, str);
171         }
172
173         str[0] = C_TOPBOTTOM;
174         str[1] = C_TOPBOTTOM;
175         wmove(radar, 0, 0);
176         for (i = 0; i < scp->width - 1; i++)
177                 waddstr(radar, str);
178         waddch(radar, C_TOPBOTTOM);
179
180         str[0] = C_TOPBOTTOM;
181         str[1] = C_TOPBOTTOM;
182         wmove(radar, scp->height - 1, 0);
183         for (i = 0; i < scp->width - 1; i++)
184                 waddstr(radar, str);
185         waddch(radar, C_TOPBOTTOM);
186
187         for (i = 1; i < scp->height - 1; i++) {
188                 wmove(radar, i, 0);
189                 waddch(radar, C_LEFTRIGHT);
190                 wmove(radar, i, (scp->width - 1) * 2);
191                 waddch(radar, C_LEFTRIGHT);
192         }
193
194         str[0] = C_BEACON;
195         for (i = 0; i < scp->num_beacons; i++) {
196                 str[1] = '0' + i;
197                 wmove(radar, scp->beacon[i].y, scp->beacon[i].x * 2);
198                 waddstr(radar, str);
199         }
200
201         for (i = 0; i < scp->num_exits; i++) {
202                 wmove(radar, scp->exit[i].y, scp->exit[i].x * 2);
203                 waddch(radar, '0' + i);
204         }
205
206         airstr = "^?>?v?<?";
207         for (i = 0; i < scp->num_airports; i++) {
208                 str[0] = airstr[scp->airport[i].dir];
209                 str[1] = '0' + i;
210                 wmove(radar, scp->airport[i].y, scp->airport[i].x * 2);
211                 waddstr(radar, str);
212         }
213
214         overwrite(radar, cleanradar);
215         wrefresh(radar);
216         wrefresh(credit);
217         fflush(stdout);
218 }
219
220 draw_line(w, x, y, lx, ly, s)
221         WINDOW          *w;
222         int             x, y, lx, ly;
223         const char      *s;
224 {
225         int     dx, dy;
226
227         dx = SGN(lx - x);
228         dy = SGN(ly - y);
229         for (;;) {
230                 wmove(w, y, x * 2);
231                 waddstr(w, s);
232                 if (x == lx && y == ly)
233                         break;
234                 x += dx;
235                 y += dy;
236         }
237 }
238
239 ioclrtoeol(pos)
240 {
241         wmove(input, 0, pos);
242         wclrtoeol(input);
243         wrefresh(input);
244         fflush(stdout);
245 }
246
247 iomove(pos)
248 {
249         wmove(input, 0, pos);
250         wrefresh(input);
251         fflush(stdout);
252 }
253
254 ioaddstr(pos, str)
255         const char      *str;
256 {
257         wmove(input, 0, pos);
258         waddstr(input, str);
259         wrefresh(input);
260         fflush(stdout);
261 }
262
263 ioclrtobot()
264 {
265         wclrtobot(input);
266         wrefresh(input);
267         fflush(stdout);
268 }
269
270 ioerror(pos, len, str)
271         const char      *str;
272 {
273         int     i;
274
275         wmove(input, 1, pos);
276         for (i = 0; i < len; i++)
277                 waddch(input, '^');
278         wmove(input, 2, 0);
279         waddstr(input, str);
280         wrefresh(input);
281         fflush(stdout);
282 }
283
284 quit()
285 {
286         int                     c, y, x;
287 #ifdef BSD
288         struct itimerval        itv;
289 #endif
290
291         getyx(input, y, x);
292         wmove(input, 2, 0);
293         waddstr(input, "Really quit? (y/n) ");
294         wclrtobot(input);
295         wrefresh(input);
296         fflush(stdout);
297
298         c = getchar();
299         if (c == EOF || c == 'y') {
300                 /* disable timer */
301 #ifdef BSD
302                 itv.it_value.tv_sec = 0;
303                 itv.it_value.tv_usec = 0;
304                 setitimer(ITIMER_REAL, &itv, NULL);
305 #endif
306 #ifdef SYSV
307                 alarm(0);
308 #endif
309                 fflush(stdout);
310                 clear();
311                 refresh();
312                 endwin();
313                 log_score(0);
314                 exit(0);
315         }
316         wmove(input, 2, 0);
317         wclrtobot(input);
318         wmove(input, y, x);
319         wrefresh(input);
320         fflush(stdout);
321         return;
322 }
323
324 planewin()
325 {
326         PLANE   *pp;
327         char    *command();
328         int     warning = 0;
329
330 #ifdef BSD
331         wclear(planes);
332 #endif
333
334         wmove(planes, 0,0);
335
336 #ifdef SYSV
337         wclrtobot(planes);
338 #endif
339         wprintw(planes, "Time: %-4d Safe: %d", clck, safe_planes);
340         wmove(planes, 2, 0);
341
342         waddstr(planes, "pl dt  comm");
343         for (pp = air.head; pp != NULL; pp = pp->next) {
344                 if (waddch(planes, '\n') == ERR) {
345                         warning++;
346                         break;
347                 }
348                 waddstr(planes, command(pp));
349         }
350         waddch(planes, '\n');
351         for (pp = ground.head; pp != NULL; pp = pp->next) {
352                 if (waddch(planes, '\n') == ERR) {
353                         warning++;
354                         break;
355                 }
356                 waddstr(planes, command(pp));
357         }
358         if (warning) {
359                 wmove(planes, LINES - INPUT_LINES - 1, 0);
360                 waddstr(planes, "---- more ----");
361                 wclrtoeol(planes);
362         }
363         wrefresh(planes);
364         fflush(stdout);
365 }
366
367 loser(p, s)
368         const PLANE     *p;
369         const char      *s;
370 {
371         int                     c;
372 #ifdef BSD
373         struct itimerval        itv;
374 #endif
375
376         /* disable timer */
377 #ifdef BSD
378         itv.it_value.tv_sec = 0;
379         itv.it_value.tv_usec = 0;
380         setitimer(ITIMER_REAL, &itv, NULL);
381 #endif
382 #ifdef SYSV
383         alarm(0);
384 #endif
385
386         wmove(input, 0, 0);
387         wclrtobot(input);
388         wprintw(input, "Plane '%c' %s\n\nHit space for top players list...",
389                 name(p), s);
390         wrefresh(input);
391         fflush(stdout);
392         while ((c = getchar()) != EOF && c != ' ')
393                 ;
394         clear();        /* move to top of screen */
395         refresh();
396         endwin();
397         log_score(0);
398         exit(0);
399 }
400
401 redraw()
402 {
403         clear();
404         refresh();
405
406         touchwin(radar);
407         wrefresh(radar);
408         touchwin(planes);
409         wrefresh(planes);
410         touchwin(credit);
411         wrefresh(credit);
412
413         /* refresh input last to get cursor in right place */
414         touchwin(input);
415         wrefresh(input);
416         fflush(stdout);
417 }
418
419
420 done_screen()
421 {
422         clear();
423         refresh();
424         endwin();         /* clean up curses */
425 }