1*79af1000Sguenther /* $OpenBSD: graphics.c,v 1.12 2016/08/27 02:02:44 guenther Exp $ */
2df930be7Sderaadt /* $NetBSD: graphics.c,v 1.3 1995/03/21 15:04:04 cgd Exp $ */
3df930be7Sderaadt
4df930be7Sderaadt /*-
5df930be7Sderaadt * Copyright (c) 1990, 1993
6df930be7Sderaadt * The Regents of the University of California. All rights reserved.
7df930be7Sderaadt *
8df930be7Sderaadt * This code is derived from software contributed to Berkeley by
9df930be7Sderaadt * Ed James.
10df930be7Sderaadt *
11df930be7Sderaadt * Redistribution and use in source and binary forms, with or without
12df930be7Sderaadt * modification, are permitted provided that the following conditions
13df930be7Sderaadt * are met:
14df930be7Sderaadt * 1. Redistributions of source code must retain the above copyright
15df930be7Sderaadt * notice, this list of conditions and the following disclaimer.
16df930be7Sderaadt * 2. Redistributions in binary form must reproduce the above copyright
17df930be7Sderaadt * notice, this list of conditions and the following disclaimer in the
18df930be7Sderaadt * documentation and/or other materials provided with the distribution.
197a09557bSmillert * 3. Neither the name of the University nor the names of its contributors
20df930be7Sderaadt * may be used to endorse or promote products derived from this software
21df930be7Sderaadt * without specific prior written permission.
22df930be7Sderaadt *
23df930be7Sderaadt * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24df930be7Sderaadt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25df930be7Sderaadt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26df930be7Sderaadt * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27df930be7Sderaadt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28df930be7Sderaadt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29df930be7Sderaadt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30df930be7Sderaadt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31df930be7Sderaadt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32df930be7Sderaadt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33df930be7Sderaadt * SUCH DAMAGE.
34df930be7Sderaadt */
35df930be7Sderaadt
36df930be7Sderaadt /*
37df930be7Sderaadt * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
38df930be7Sderaadt *
39df930be7Sderaadt * Copy permission is hereby granted provided that this notice is
40df930be7Sderaadt * retained on all partial or complete copies.
41df930be7Sderaadt *
42df930be7Sderaadt * For more info on this and all of my stuff, mail edjames@berkeley.edu.
43df930be7Sderaadt */
44df930be7Sderaadt
45*79af1000Sguenther #include <sys/time.h>
462317ec67Smestre #include <curses.h>
4731aab2a5Spjanzen #include <err.h>
482317ec67Smestre #include <stdlib.h>
492317ec67Smestre
502317ec67Smestre #include "def.h"
512317ec67Smestre #include "extern.h"
52df930be7Sderaadt
53df930be7Sderaadt #define C_TOPBOTTOM '-'
54df930be7Sderaadt #define C_LEFTRIGHT '|'
55df930be7Sderaadt #define C_AIRPORT '='
56df930be7Sderaadt #define C_LINE '+'
57df930be7Sderaadt #define C_BACKROUND '.'
58df930be7Sderaadt #define C_BEACON '*'
59df930be7Sderaadt #define C_CREDIT '*'
60df930be7Sderaadt
61df930be7Sderaadt WINDOW *radar, *cleanradar, *credit, *input, *planes;
62df930be7Sderaadt
6331aab2a5Spjanzen int
getAChar(void)643eb8c9edSjsg getAChar(void)
65df930be7Sderaadt {
66859369c2Spjanzen int c;
6754740ad2Stedu
68859369c2Spjanzen if ((c = getchar()) == EOF && feof(stdin))
69859369c2Spjanzen quit(0);
70859369c2Spjanzen return (c);
71df930be7Sderaadt }
72df930be7Sderaadt
7331aab2a5Spjanzen void
erase_all(void)743eb8c9edSjsg erase_all(void)
75df930be7Sderaadt {
76df930be7Sderaadt PLANE *pp;
77df930be7Sderaadt
78df930be7Sderaadt for (pp = air.head; pp != NULL; pp = pp->next) {
79df930be7Sderaadt wmove(cleanradar, pp->ypos, pp->xpos * 2);
80df930be7Sderaadt wmove(radar, pp->ypos, pp->xpos * 2);
81df930be7Sderaadt waddch(radar, winch(cleanradar));
82df930be7Sderaadt wmove(cleanradar, pp->ypos, pp->xpos * 2 + 1);
83df930be7Sderaadt wmove(radar, pp->ypos, pp->xpos * 2 + 1);
84df930be7Sderaadt waddch(radar, winch(cleanradar));
85df930be7Sderaadt }
86df930be7Sderaadt }
87df930be7Sderaadt
8831aab2a5Spjanzen void
draw_all(void)893eb8c9edSjsg draw_all(void)
90df930be7Sderaadt {
91df930be7Sderaadt PLANE *pp;
92df930be7Sderaadt
93df930be7Sderaadt for (pp = air.head; pp != NULL; pp = pp->next) {
94df930be7Sderaadt if (pp->status == S_MARKED)
95df930be7Sderaadt wstandout(radar);
96df930be7Sderaadt wmove(radar, pp->ypos, pp->xpos * 2);
97df930be7Sderaadt waddch(radar, name(pp));
98df930be7Sderaadt waddch(radar, '0' + pp->altitude);
99df930be7Sderaadt if (pp->status == S_MARKED)
100df930be7Sderaadt wstandend(radar);
101df930be7Sderaadt }
102df930be7Sderaadt wrefresh(radar);
103df930be7Sderaadt planewin();
104df930be7Sderaadt wrefresh(input); /* return cursor */
105df930be7Sderaadt fflush(stdout);
106df930be7Sderaadt }
107df930be7Sderaadt
10831aab2a5Spjanzen void
setup_screen(const C_SCREEN * scp)1093eb8c9edSjsg setup_screen(const C_SCREEN *scp)
110df930be7Sderaadt {
111df930be7Sderaadt static char buffer[BUFSIZ];
1125803e5dcSpjanzen int i, j;
1135803e5dcSpjanzen char str[3];
1145803e5dcSpjanzen const char *airstr;
115df930be7Sderaadt
116df930be7Sderaadt initscr();
1175803e5dcSpjanzen /* size of screen depends on chosen game, but we need at least 80
1185803e5dcSpjanzen * columns for "Information area" to work. */
1195803e5dcSpjanzen if (LINES < (INPUT_LINES + scp->height) ||
1205803e5dcSpjanzen COLS < (PLANE_COLS + 2 * scp->width) ||
1215803e5dcSpjanzen COLS < 80) {
12231aab2a5Spjanzen endwin();
12331aab2a5Spjanzen errx(1, "screen too small.");
12431aab2a5Spjanzen }
12533206277Stedu setvbuf(stdout, buffer, _IOFBF, sizeof buffer);
126df930be7Sderaadt input = newwin(INPUT_LINES, COLS - PLANE_COLS, LINES - INPUT_LINES, 0);
127df930be7Sderaadt credit = newwin(INPUT_LINES, PLANE_COLS, LINES - INPUT_LINES,
128df930be7Sderaadt COLS - PLANE_COLS);
129df930be7Sderaadt planes = newwin(LINES - INPUT_LINES, PLANE_COLS, 0, COLS - PLANE_COLS);
130df930be7Sderaadt
131df930be7Sderaadt str[2] = '\0';
132df930be7Sderaadt
133df930be7Sderaadt if (radar != NULL)
134df930be7Sderaadt delwin(radar);
135df930be7Sderaadt radar = newwin(scp->height, scp->width * 2, 0, 0);
136df930be7Sderaadt
137df930be7Sderaadt if (cleanradar != NULL)
138df930be7Sderaadt delwin(cleanradar);
139df930be7Sderaadt cleanradar = newwin(scp->height, scp->width * 2, 0, 0);
140df930be7Sderaadt
141df930be7Sderaadt /* minus one here to prevent a scroll */
142df930be7Sderaadt for (i = 0; i < PLANE_COLS - 1; i++) {
143df930be7Sderaadt wmove(credit, 0, i);
144df930be7Sderaadt waddch(credit, C_CREDIT);
145df930be7Sderaadt wmove(credit, INPUT_LINES - 1, i);
146df930be7Sderaadt waddch(credit, C_CREDIT);
147df930be7Sderaadt }
148df930be7Sderaadt wmove(credit, INPUT_LINES / 2, 1);
149df930be7Sderaadt waddstr(credit, AUTHOR_STR);
150df930be7Sderaadt
151df930be7Sderaadt for (i = 1; i < scp->height - 1; i++) {
152df930be7Sderaadt for (j = 1; j < scp->width - 1; j++) {
153df930be7Sderaadt wmove(radar, i, j * 2);
154df930be7Sderaadt waddch(radar, C_BACKROUND);
155df930be7Sderaadt }
156df930be7Sderaadt }
157df930be7Sderaadt
158df930be7Sderaadt /*
159df930be7Sderaadt * Draw the lines first, since people like to draw lines
160df930be7Sderaadt * through beacons and exit points.
161df930be7Sderaadt */
162df930be7Sderaadt str[0] = C_LINE;
163df930be7Sderaadt for (i = 0; i < scp->num_lines; i++) {
164df930be7Sderaadt str[1] = ' ';
165df930be7Sderaadt draw_line(radar, scp->line[i].p1.x, scp->line[i].p1.y,
166df930be7Sderaadt scp->line[i].p2.x, scp->line[i].p2.y, str);
167df930be7Sderaadt }
168df930be7Sderaadt
169df930be7Sderaadt str[0] = C_TOPBOTTOM;
170df930be7Sderaadt str[1] = C_TOPBOTTOM;
171df930be7Sderaadt wmove(radar, 0, 0);
172df930be7Sderaadt for (i = 0; i < scp->width - 1; i++)
173df930be7Sderaadt waddstr(radar, str);
174df930be7Sderaadt waddch(radar, C_TOPBOTTOM);
175df930be7Sderaadt
176df930be7Sderaadt str[0] = C_TOPBOTTOM;
177df930be7Sderaadt str[1] = C_TOPBOTTOM;
178df930be7Sderaadt wmove(radar, scp->height - 1, 0);
179df930be7Sderaadt for (i = 0; i < scp->width - 1; i++)
180df930be7Sderaadt waddstr(radar, str);
181df930be7Sderaadt waddch(radar, C_TOPBOTTOM);
182df930be7Sderaadt
183df930be7Sderaadt for (i = 1; i < scp->height - 1; i++) {
184df930be7Sderaadt wmove(radar, i, 0);
185df930be7Sderaadt waddch(radar, C_LEFTRIGHT);
186df930be7Sderaadt wmove(radar, i, (scp->width - 1) * 2);
187df930be7Sderaadt waddch(radar, C_LEFTRIGHT);
188df930be7Sderaadt }
189df930be7Sderaadt
190df930be7Sderaadt str[0] = C_BEACON;
191df930be7Sderaadt for (i = 0; i < scp->num_beacons; i++) {
192df930be7Sderaadt str[1] = '0' + i;
193df930be7Sderaadt wmove(radar, scp->beacon[i].y, scp->beacon[i].x * 2);
194df930be7Sderaadt waddstr(radar, str);
195df930be7Sderaadt }
196df930be7Sderaadt
197df930be7Sderaadt for (i = 0; i < scp->num_exits; i++) {
198df930be7Sderaadt wmove(radar, scp->exit[i].y, scp->exit[i].x * 2);
199df930be7Sderaadt waddch(radar, '0' + i);
200df930be7Sderaadt }
201df930be7Sderaadt
202df930be7Sderaadt airstr = "^?>?v?<?";
203df930be7Sderaadt for (i = 0; i < scp->num_airports; i++) {
204df930be7Sderaadt str[0] = airstr[scp->airport[i].dir];
205df930be7Sderaadt str[1] = '0' + i;
206df930be7Sderaadt wmove(radar, scp->airport[i].y, scp->airport[i].x * 2);
207df930be7Sderaadt waddstr(radar, str);
208df930be7Sderaadt }
209df930be7Sderaadt
210df930be7Sderaadt overwrite(radar, cleanradar);
211df930be7Sderaadt wrefresh(radar);
212df930be7Sderaadt wrefresh(credit);
213df930be7Sderaadt fflush(stdout);
214df930be7Sderaadt }
215df930be7Sderaadt
21631aab2a5Spjanzen void
draw_line(WINDOW * w,int x,int y,int lx,int ly,const char * s)2173eb8c9edSjsg draw_line(WINDOW *w, int x, int y, int lx, int ly, const char *s)
218df930be7Sderaadt {
219df930be7Sderaadt int dx, dy;
220df930be7Sderaadt
221df930be7Sderaadt dx = SGN(lx - x);
222df930be7Sderaadt dy = SGN(ly - y);
223df930be7Sderaadt for (;;) {
224df930be7Sderaadt wmove(w, y, x * 2);
225df930be7Sderaadt waddstr(w, s);
226df930be7Sderaadt if (x == lx && y == ly)
227df930be7Sderaadt break;
228df930be7Sderaadt x += dx;
229df930be7Sderaadt y += dy;
230df930be7Sderaadt }
231df930be7Sderaadt }
232df930be7Sderaadt
23331aab2a5Spjanzen void
ioclrtoeol(int pos)2343eb8c9edSjsg ioclrtoeol(int pos)
235df930be7Sderaadt {
236df930be7Sderaadt wmove(input, 0, pos);
237df930be7Sderaadt wclrtoeol(input);
238df930be7Sderaadt wrefresh(input);
239df930be7Sderaadt fflush(stdout);
240df930be7Sderaadt }
241df930be7Sderaadt
24231aab2a5Spjanzen void
iomove(int pos)2433eb8c9edSjsg iomove(int pos)
244df930be7Sderaadt {
245df930be7Sderaadt wmove(input, 0, pos);
246df930be7Sderaadt wrefresh(input);
247df930be7Sderaadt fflush(stdout);
248df930be7Sderaadt }
249df930be7Sderaadt
25031aab2a5Spjanzen void
ioaddstr(int pos,const char * str)2513eb8c9edSjsg ioaddstr(int pos, const char *str)
252df930be7Sderaadt {
253df930be7Sderaadt wmove(input, 0, pos);
254df930be7Sderaadt waddstr(input, str);
255df930be7Sderaadt wrefresh(input);
256df930be7Sderaadt fflush(stdout);
257df930be7Sderaadt }
258df930be7Sderaadt
25931aab2a5Spjanzen void
ioclrtobot(void)2603eb8c9edSjsg ioclrtobot(void)
261df930be7Sderaadt {
262df930be7Sderaadt wclrtobot(input);
263df930be7Sderaadt wrefresh(input);
264df930be7Sderaadt fflush(stdout);
265df930be7Sderaadt }
266df930be7Sderaadt
26731aab2a5Spjanzen void
ioerror(int pos,int len,const char * str)2683eb8c9edSjsg ioerror(int pos, int len, const char *str)
269df930be7Sderaadt {
270df930be7Sderaadt int i;
271df930be7Sderaadt
272df930be7Sderaadt wmove(input, 1, pos);
273df930be7Sderaadt for (i = 0; i < len; i++)
274df930be7Sderaadt waddch(input, '^');
275df930be7Sderaadt wmove(input, 2, 0);
276df930be7Sderaadt waddstr(input, str);
277df930be7Sderaadt wrefresh(input);
278df930be7Sderaadt fflush(stdout);
279df930be7Sderaadt }
280df930be7Sderaadt
28131aab2a5Spjanzen void
quit(int dummy)2823eb8c9edSjsg quit(int dummy)
283df930be7Sderaadt {
284df930be7Sderaadt int c, y, x;
285df930be7Sderaadt struct itimerval itv;
286df930be7Sderaadt
287df930be7Sderaadt getyx(input, y, x);
288df930be7Sderaadt wmove(input, 2, 0);
289df930be7Sderaadt waddstr(input, "Really quit? (y/n) ");
290df930be7Sderaadt wclrtobot(input);
291df930be7Sderaadt wrefresh(input);
292df930be7Sderaadt fflush(stdout);
293df930be7Sderaadt
294df930be7Sderaadt c = getchar();
295df930be7Sderaadt if (c == EOF || c == 'y') {
296df930be7Sderaadt /* disable timer */
297df930be7Sderaadt itv.it_value.tv_sec = 0;
298df930be7Sderaadt itv.it_value.tv_usec = 0;
299df930be7Sderaadt setitimer(ITIMER_REAL, &itv, NULL);
300df930be7Sderaadt fflush(stdout);
301df930be7Sderaadt clear();
302df930be7Sderaadt refresh();
303df930be7Sderaadt endwin();
304df930be7Sderaadt log_score(0);
305df930be7Sderaadt exit(0);
306df930be7Sderaadt }
307df930be7Sderaadt wmove(input, 2, 0);
308df930be7Sderaadt wclrtobot(input);
309df930be7Sderaadt wmove(input, y, x);
310df930be7Sderaadt wrefresh(input);
311df930be7Sderaadt fflush(stdout);
312df930be7Sderaadt }
313df930be7Sderaadt
31431aab2a5Spjanzen void
planewin(void)3153eb8c9edSjsg planewin(void)
316df930be7Sderaadt {
317df930be7Sderaadt PLANE *pp;
318df930be7Sderaadt int warning = 0;
319df930be7Sderaadt
320df930be7Sderaadt wclear(planes);
321df930be7Sderaadt
322df930be7Sderaadt wmove(planes, 0,0);
323df930be7Sderaadt
324df930be7Sderaadt wprintw(planes, "Time: %-4d Safe: %d", clck, safe_planes);
325df930be7Sderaadt wmove(planes, 2, 0);
326df930be7Sderaadt
327df930be7Sderaadt waddstr(planes, "pl dt comm");
328df930be7Sderaadt for (pp = air.head; pp != NULL; pp = pp->next) {
329df930be7Sderaadt if (waddch(planes, '\n') == ERR) {
330df930be7Sderaadt warning++;
331df930be7Sderaadt break;
332df930be7Sderaadt }
333df930be7Sderaadt waddstr(planes, command(pp));
334df930be7Sderaadt }
335df930be7Sderaadt waddch(planes, '\n');
336df930be7Sderaadt for (pp = ground.head; pp != NULL; pp = pp->next) {
337df930be7Sderaadt if (waddch(planes, '\n') == ERR) {
338df930be7Sderaadt warning++;
339df930be7Sderaadt break;
340df930be7Sderaadt }
341df930be7Sderaadt waddstr(planes, command(pp));
342df930be7Sderaadt }
343df930be7Sderaadt if (warning) {
344df930be7Sderaadt wmove(planes, LINES - INPUT_LINES - 1, 0);
345df930be7Sderaadt waddstr(planes, "---- more ----");
346df930be7Sderaadt wclrtoeol(planes);
347df930be7Sderaadt }
348df930be7Sderaadt wrefresh(planes);
349df930be7Sderaadt fflush(stdout);
350df930be7Sderaadt }
351df930be7Sderaadt
35231aab2a5Spjanzen void
loser(const PLANE * p,const char * s)3533eb8c9edSjsg loser(const PLANE *p, const char *s)
354df930be7Sderaadt {
355df930be7Sderaadt int c;
356df930be7Sderaadt struct itimerval itv;
357df930be7Sderaadt
358df930be7Sderaadt /* disable timer */
359df930be7Sderaadt itv.it_value.tv_sec = 0;
360df930be7Sderaadt itv.it_value.tv_usec = 0;
361df930be7Sderaadt setitimer(ITIMER_REAL, &itv, NULL);
362df930be7Sderaadt
363df930be7Sderaadt wmove(input, 0, 0);
364df930be7Sderaadt wclrtobot(input);
365d9559820Spjanzen if (p == NULL)
366d9559820Spjanzen wprintw(input, "%s\n\nHit space for top players list...", s);
367d9559820Spjanzen else
368df930be7Sderaadt wprintw(input, "Plane '%c' %s\n\nHit space for top players list...",
369df930be7Sderaadt name(p), s);
370df930be7Sderaadt wrefresh(input);
371df930be7Sderaadt fflush(stdout);
372df930be7Sderaadt while ((c = getchar()) != EOF && c != ' ')
373df930be7Sderaadt ;
374df930be7Sderaadt clear(); /* move to top of screen */
375df930be7Sderaadt refresh();
376df930be7Sderaadt endwin();
377df930be7Sderaadt log_score(0);
378df930be7Sderaadt exit(0);
379df930be7Sderaadt }
380df930be7Sderaadt
38131aab2a5Spjanzen void
redraw(void)3823eb8c9edSjsg redraw(void)
383df930be7Sderaadt {
384df930be7Sderaadt clear();
385df930be7Sderaadt refresh();
386df930be7Sderaadt
387df930be7Sderaadt touchwin(radar);
388df930be7Sderaadt wrefresh(radar);
389df930be7Sderaadt touchwin(planes);
390df930be7Sderaadt wrefresh(planes);
391df930be7Sderaadt touchwin(credit);
392df930be7Sderaadt wrefresh(credit);
393df930be7Sderaadt
394df930be7Sderaadt /* refresh input last to get cursor in right place */
395df930be7Sderaadt touchwin(input);
396df930be7Sderaadt wrefresh(input);
397df930be7Sderaadt fflush(stdout);
398df930be7Sderaadt }
399df930be7Sderaadt
40031aab2a5Spjanzen void
done_screen(void)4013eb8c9edSjsg done_screen(void)
402df930be7Sderaadt {
403df930be7Sderaadt clear();
404df930be7Sderaadt refresh();
405df930be7Sderaadt endwin(); /* clean up curses */
406df930be7Sderaadt }
407