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