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