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