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 } 426