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