(linenum→info "unix/slp.c:2238")

bsd-games/2.17/sail/pl_7.c

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