1 /* $OpenBSD: pl_7.c,v 1.8 2003/06/03 03:01:41 millert Exp $ */ 2 /* $NetBSD: pl_7.c,v 1.6 1995/04/22 10:37:17 cgd Exp $ */ 3 4 /* 5 * Copyright (c) 1983, 1993 6 * The Regents of the University of California. All rights reserved. 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. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #ifndef lint 34 #if 0 35 static char sccsid[] = "@(#)pl_7.c 8.1 (Berkeley) 5/31/93"; 36 #else 37 static char rcsid[] = "$OpenBSD: pl_7.c,v 1.8 2003/06/03 03:01:41 millert Exp $"; 38 #endif 39 #endif /* not lint */ 40 41 #include <sys/ttydefaults.h> 42 #include "player.h" 43 #include <stdarg.h> 44 #include <unistd.h> 45 #include <err.h> 46 47 48 /* 49 * Display interface 50 */ 51 52 static char sc_hasprompt; 53 static const char *sc_prompt; 54 static const char *sc_buf; 55 static int sc_line; 56 57 WINDOW *view_w; 58 WINDOW *slot_w; 59 WINDOW *scroll_w; 60 WINDOW *stat_w; 61 WINDOW *turn_w; 62 63 char done_curses; 64 char loaded, fired, changed, repaired; 65 char dont_adjust; 66 int viewrow, viewcol; 67 char movebuf[sizeof SHIP(0)->file->movebuf]; 68 int player; 69 struct ship *ms; /* memorial structure, &cc->ship[player] */ 70 struct File *mf; /* ms->file */ 71 struct shipspecs *mc; /* ms->specs */ 72 73 void 74 initscreen() 75 { 76 if (!SCREENTEST()) 77 errx(1, "can't sail on this terminal."); 78 /* initscr() already done in SCREENTEST() */ 79 view_w = newwin(VIEW_Y, VIEW_X, VIEW_T, VIEW_L); 80 slot_w = newwin(SLOT_Y, SLOT_X, SLOT_T, SLOT_L); 81 scroll_w = newwin(SCROLL_Y, SCROLL_X, SCROLL_T, SCROLL_L); 82 stat_w = newwin(STAT_Y, STAT_X, STAT_T, STAT_L); 83 turn_w = newwin(TURN_Y, TURN_X, TURN_T, TURN_L); 84 done_curses++; 85 (void) leaveok(view_w, 1); 86 (void) leaveok(slot_w, 1); 87 (void) leaveok(stat_w, 1); 88 (void) leaveok(turn_w, 1); 89 noecho(); 90 cbreak(); 91 } 92 93 void 94 cleanupscreen() 95 { 96 /* alarm already turned off */ 97 if (done_curses) { 98 (void) wmove(scroll_w, SCROLL_Y - 1, 0); 99 (void) wclrtoeol(scroll_w); 100 draw_screen(); 101 endwin(); 102 } 103 } 104 105 /* ARGSUSED */ 106 void 107 newturn(n) 108 int n; 109 { 110 repaired = loaded = fired = changed = 0; 111 movebuf[0] = '\0'; 112 113 (void) alarm(0); 114 if (mf->readyL & R_LOADING) { 115 if (mf->readyL & R_DOUBLE) 116 mf->readyL = R_LOADING; 117 else 118 mf->readyL = R_LOADED; 119 } 120 if (mf->readyR & R_LOADING) { 121 if (mf->readyR & R_DOUBLE) 122 mf->readyR = R_LOADING; 123 else 124 mf->readyR = R_LOADED; 125 } 126 if (!hasdriver) 127 Write(W_DDEAD, SHIP(0), 0, 0, 0, 0); 128 129 if (sc_hasprompt) { 130 (void) wmove(scroll_w, sc_line, 0); 131 (void) wclrtoeol(scroll_w); 132 } 133 if (Sync() < 0) 134 leave(LEAVE_SYNC); 135 if (!hasdriver) 136 leave(LEAVE_DRIVER); 137 if (sc_hasprompt) 138 (void) wprintw(scroll_w, "%s%s", sc_prompt, sc_buf); 139 140 if (turn % 50 == 0) 141 Write(W_ALIVE, SHIP(0), 0, 0, 0, 0); 142 if (mf->FS && (!mc->rig1 || windspeed == 6)) 143 Write(W_FS, ms, 0, 0, 0, 0); 144 if (mf->FS == 1) 145 Write(W_FS, ms, 2, 0, 0, 0); 146 147 if (mf->struck) 148 leave(LEAVE_QUIT); 149 if (mf->captured != 0) 150 leave(LEAVE_CAPTURED); 151 if (windspeed == 7) 152 leave(LEAVE_HURRICAN); 153 154 adjustview(); 155 draw_screen(); 156 157 (void) signal(SIGALRM, newturn); 158 (void) alarm(7); 159 } 160 161 /*VARARGS2*/ 162 void 163 Signal(char *fmt, struct ship *ship, ...) 164 { 165 va_list ap; 166 char format[BUFSIZ]; 167 168 va_start(ap, ship); 169 if (!done_curses) { 170 va_end(ap); 171 return; 172 } 173 if (*fmt == '\7') 174 putchar(*fmt++); 175 fmtship(format, sizeof(format), fmt, ship); 176 (void) vw_printw(scroll_w, format, ap); 177 va_end(ap); 178 Scroll(); 179 } 180 181 /*VARARGS2*/ 182 void 183 Msg(char *fmt, ...) 184 { 185 va_list ap; 186 187 va_start(ap, fmt); 188 189 if (!done_curses) { 190 va_end(ap); 191 return; 192 } 193 if (*fmt == '\7') 194 putchar(*fmt++); 195 (void) vw_printw(scroll_w, fmt, ap); 196 va_end(ap); 197 Scroll(); 198 } 199 200 void 201 Scroll() 202 { 203 if (++sc_line >= SCROLL_Y) 204 sc_line = 0; 205 (void) wmove(scroll_w, sc_line, 0); 206 (void) wclrtoeol(scroll_w); 207 } 208 209 void 210 prompt(p, ship) 211 const char *p; 212 struct ship *ship; 213 { 214 static char buf[BUFSIZ]; 215 216 fmtship(buf, sizeof(buf), p, ship); 217 sc_prompt = buf; 218 sc_buf = ""; 219 sc_hasprompt = 1; 220 (void) waddstr(scroll_w, buf); 221 } 222 223 void 224 endprompt(flag) 225 char flag; 226 { 227 sc_hasprompt = 0; 228 if (flag) 229 Scroll(); 230 } 231 232 int 233 sgetch(p, ship, flag) 234 const char *p; 235 struct ship *ship; 236 char flag; 237 { 238 int c; 239 240 prompt(p, ship); 241 blockalarm(); 242 (void) wrefresh(scroll_w); 243 unblockalarm(); 244 while ((c = wgetch(scroll_w)) == EOF) 245 ; 246 if (flag && c >= ' ' && c < 0x7f) 247 (void) waddch(scroll_w, c); 248 endprompt(flag); 249 return c; 250 } 251 252 void 253 sgetstr(pr, buf, n) 254 const char *pr; 255 char *buf; 256 int n; 257 { 258 int c; 259 char *p = buf; 260 261 prompt(pr, (struct ship *)0); 262 sc_buf = buf; 263 for (;;) { 264 *p = 0; 265 blockalarm(); 266 (void) wrefresh(scroll_w); 267 unblockalarm(); 268 while ((c = wgetch(scroll_w)) == EOF) 269 ; 270 switch (c) { 271 case '\n': 272 case '\r': 273 endprompt(1); 274 return; 275 case '\b': 276 if (p > buf) { 277 (void) waddstr(scroll_w, "\b \b"); 278 p--; 279 } 280 break; 281 default: 282 if (c >= ' ' && c < 0x7f && p < buf + n - 1) { 283 *p++ = c; 284 (void) waddch(scroll_w, c); 285 } else 286 (void) putchar('\a'); 287 } 288 } 289 } 290 291 void 292 draw_screen() 293 { 294 draw_view(); 295 draw_turn(); 296 draw_stat(); 297 draw_slot(); 298 (void) wrefresh(scroll_w); /* move the cursor */ 299 } 300 301 void 302 draw_view() 303 { 304 struct ship *sp; 305 306 (void) werase(view_w); 307 foreachship(sp) { 308 if (sp->file->dir 309 && sp->file->row > viewrow 310 && sp->file->row < viewrow + VIEW_Y 311 && sp->file->col > viewcol 312 && sp->file->col < viewcol + VIEW_X) { 313 (void) wmove(view_w, sp->file->row - viewrow, 314 sp->file->col - viewcol); 315 (void) waddch(view_w, colours(sp)); 316 (void) wmove(view_w, 317 sternrow(sp) - viewrow, 318 sterncol(sp) - viewcol); 319 (void) waddch(view_w, sterncolour(sp)); 320 } 321 } 322 (void) wrefresh(view_w); 323 } 324 325 void 326 draw_turn() 327 { 328 (void) wmove(turn_w, 0, 0); 329 (void) wprintw(turn_w, "%cTurn %d", dont_adjust?'*':'-', turn); 330 (void) wrefresh(turn_w); 331 } 332 333 void 334 draw_stat() 335 { 336 (void) wmove(stat_w, STAT_1, 0); 337 (void) wprintw(stat_w, "Points %3d\n", mf->points); 338 (void) wprintw(stat_w, "Fouls %2d\n", fouled(ms)); 339 (void) wprintw(stat_w, "Grapples %2d\n", grappled(ms)); 340 341 (void) wmove(stat_w, STAT_2, 0); 342 (void) wprintw(stat_w, " 0 %c(%c)\n", 343 maxmove(ms, winddir + 3, -1) + '0', 344 maxmove(ms, winddir + 3, 1) + '0'); 345 (void) waddstr(stat_w, " \\|/\n"); 346 (void) wprintw(stat_w, " -^-%c(%c)\n", 347 maxmove(ms, winddir + 2, -1) + '0', 348 maxmove(ms, winddir + 2, 1) + '0'); 349 (void) waddstr(stat_w, " /|\\\n"); 350 (void) wprintw(stat_w, " | %c(%c)\n", 351 maxmove(ms, winddir + 1, -1) + '0', 352 maxmove(ms, winddir + 1, 1) + '0'); 353 (void) wprintw(stat_w, " %c(%c)\n", 354 maxmove(ms, winddir, -1) + '0', 355 maxmove(ms, winddir, 1) + '0'); 356 357 (void) wmove(stat_w, STAT_3, 0); 358 (void) wprintw(stat_w, "Load %c%c %c%c\n", 359 loadname[mf->loadL], readyname(mf->readyL), 360 loadname[mf->loadR], readyname(mf->readyR)); 361 (void) wprintw(stat_w, "Hull %2d\n", mc->hull); 362 (void) wprintw(stat_w, "Crew %2d %2d %2d\n", 363 mc->crew1, mc->crew2, mc->crew3); 364 (void) wprintw(stat_w, "Guns %2d %2d\n", mc->gunL, mc->gunR); 365 (void) wprintw(stat_w, "Carr %2d %2d\n", mc->carL, mc->carR); 366 (void) wprintw(stat_w, "Rigg %d %d %d ", mc->rig1, mc->rig2, mc->rig3); 367 if (mc->rig4 < 0) 368 (void) waddch(stat_w, '-'); 369 else 370 (void) wprintw(stat_w, "%d", mc->rig4); 371 (void) wrefresh(stat_w); 372 } 373 374 void 375 draw_slot() 376 { 377 if (!boarding(ms, 0)) { 378 (void) mvwaddstr(slot_w, 0, 0, " "); 379 (void) mvwaddstr(slot_w, 1, 0, " "); 380 } else 381 (void) mvwaddstr(slot_w, 1, 0, "OBP"); 382 if (!boarding(ms, 1)) { 383 (void) mvwaddstr(slot_w, 2, 0, " "); 384 (void) mvwaddstr(slot_w, 3, 0, " "); 385 } else 386 (void) mvwaddstr(slot_w, 3, 0, "DBP"); 387 388 (void) wmove(slot_w, SLOT_Y-4, 0); 389 if (mf->RH) 390 (void) wprintw(slot_w, "%dRH", mf->RH); 391 else 392 (void) waddstr(slot_w, " "); 393 (void) wmove(slot_w, SLOT_Y-3, 0); 394 if (mf->RG) 395 (void) wprintw(slot_w, "%dRG", mf->RG); 396 else 397 (void) waddstr(slot_w, " "); 398 (void) wmove(slot_w, SLOT_Y-2, 0); 399 if (mf->RR) 400 (void) wprintw(slot_w, "%dRR", mf->RR); 401 else 402 (void) waddstr(slot_w, " "); 403 404 #define Y (SLOT_Y/2) 405 (void) wmove(slot_w, 7, 1); 406 (void) wprintw(slot_w,"%d", windspeed); 407 (void) mvwaddch(slot_w, Y, 0, ' '); 408 (void) mvwaddch(slot_w, Y, 2, ' '); 409 (void) mvwaddch(slot_w, Y-1, 0, ' '); 410 (void) mvwaddch(slot_w, Y-1, 1, ' '); 411 (void) mvwaddch(slot_w, Y-1, 2, ' '); 412 (void) mvwaddch(slot_w, Y+1, 0, ' '); 413 (void) mvwaddch(slot_w, Y+1, 1, ' '); 414 (void) mvwaddch(slot_w, Y+1, 2, ' '); 415 (void) wmove(slot_w, Y - dr[winddir], 1 - dc[winddir]); 416 switch (winddir) { 417 case 1: 418 case 5: 419 (void) waddch(slot_w, '|'); 420 break; 421 case 2: 422 case 6: 423 (void) waddch(slot_w, '/'); 424 break; 425 case 3: 426 case 7: 427 (void) waddch(slot_w, '-'); 428 break; 429 case 4: 430 case 8: 431 (void) waddch(slot_w, '\\'); 432 break; 433 } 434 (void) mvwaddch(slot_w, Y + dr[winddir], 1 + dc[winddir], '+'); 435 (void) wrefresh(slot_w); 436 } 437 438 void 439 draw_board() 440 { 441 int n; 442 443 (void) clear(); 444 (void) werase(view_w); 445 (void) werase(slot_w); 446 (void) werase(scroll_w); 447 (void) werase(stat_w); 448 (void) werase(turn_w); 449 450 sc_line = 0; 451 452 (void) move(BOX_T, BOX_L); 453 for (n = 0; n < BOX_X; n++) 454 (void) addch('-'); 455 (void) move(BOX_B, BOX_L); 456 for (n = 0; n < BOX_X; n++) 457 (void) addch('-'); 458 for (n = BOX_T+1; n < BOX_B; n++) { 459 (void) mvaddch(n, BOX_L, '|'); 460 (void) mvaddch(n, BOX_R, '|'); 461 } 462 (void) mvaddch(BOX_T, BOX_L, '+'); 463 (void) mvaddch(BOX_T, BOX_R, '+'); 464 (void) mvaddch(BOX_B, BOX_L, '+'); 465 (void) mvaddch(BOX_B, BOX_R, '+'); 466 (void) refresh(); 467 468 #define WSaIM "Wooden Ships & Iron Men" 469 (void) wmove(view_w, 2, (VIEW_X - sizeof WSaIM - 1) / 2); 470 (void) waddstr(view_w, WSaIM); 471 (void) wmove(view_w, 4, (VIEW_X - strlen(cc->name)) / 2); 472 (void) waddstr(view_w, cc->name); 473 (void) wrefresh(view_w); 474 475 (void) move(LINE_T, LINE_L); 476 (void) printw("Class %d %s (%d guns) '%s' (%c%c)", 477 mc->class, 478 classname[mc->class], 479 mc->guns, 480 ms->shipname, 481 colours(ms), 482 sterncolour(ms)); 483 (void) refresh(); 484 } 485 486 void 487 centerview() 488 { 489 viewrow = mf->row - VIEW_Y / 2; 490 viewcol = mf->col - VIEW_X / 2; 491 } 492 493 void 494 upview() 495 { 496 viewrow -= VIEW_Y / 3; 497 } 498 499 void 500 downview() 501 { 502 viewrow += VIEW_Y / 3; 503 } 504 505 void 506 leftview() 507 { 508 viewcol -= VIEW_X / 5; 509 } 510 511 void 512 rightview() 513 { 514 viewcol += VIEW_X / 5; 515 } 516 517 void 518 adjustview() 519 { 520 if (dont_adjust) 521 return; 522 if (mf->row < viewrow + VIEW_Y/4) 523 viewrow = mf->row - (VIEW_Y - VIEW_Y/4); 524 else if (mf->row > viewrow + (VIEW_Y - VIEW_Y/4)) 525 viewrow = mf->row - VIEW_Y/4; 526 if (mf->col < viewcol + VIEW_X/8) 527 viewcol = mf->col - (VIEW_X - VIEW_X/8); 528 else if (mf->col > viewcol + (VIEW_X - VIEW_X/8)) 529 viewcol = mf->col - VIEW_X/8; 530 } 531