Home | History | Annotate | Line # | Download | only in sail
      1  1.42  dholland /*	$NetBSD: pl_7.c,v 1.42 2011/08/26 06:18:18 dholland Exp $	*/
      2   1.6       cgd 
      3   1.1       cgd /*
      4   1.6       cgd  * Copyright (c) 1983, 1993
      5   1.6       cgd  *	The Regents of the University of California.  All rights reserved.
      6   1.1       cgd  *
      7   1.1       cgd  * Redistribution and use in source and binary forms, with or without
      8   1.1       cgd  * modification, are permitted provided that the following conditions
      9   1.1       cgd  * are met:
     10   1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     11   1.1       cgd  *    notice, this list of conditions and the following disclaimer.
     12   1.1       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     13   1.1       cgd  *    notice, this list of conditions and the following disclaimer in the
     14   1.1       cgd  *    documentation and/or other materials provided with the distribution.
     15  1.27       agc  * 3. Neither the name of the University nor the names of its contributors
     16   1.1       cgd  *    may be used to endorse or promote products derived from this software
     17   1.1       cgd  *    without specific prior written permission.
     18   1.1       cgd  *
     19   1.1       cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20   1.1       cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21   1.1       cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22   1.1       cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23   1.1       cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24   1.1       cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25   1.1       cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26   1.1       cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27   1.1       cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28   1.1       cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29   1.1       cgd  * SUCH DAMAGE.
     30   1.1       cgd  */
     31   1.1       cgd 
     32   1.7  christos #include <sys/cdefs.h>
     33   1.1       cgd #ifndef lint
     34   1.6       cgd #if 0
     35   1.6       cgd static char sccsid[] = "@(#)pl_7.c	8.1 (Berkeley) 5/31/93";
     36   1.6       cgd #else
     37  1.42  dholland __RCSID("$NetBSD: pl_7.c,v 1.42 2011/08/26 06:18:18 dholland Exp $");
     38   1.6       cgd #endif
     39   1.1       cgd #endif /* not lint */
     40   1.1       cgd 
     41  1.20     jwise #include <curses.h>
     42  1.29  dholland #include <err.h>
     43  1.35  dholland #include <errno.h>
     44  1.19     jwise #include <signal.h>
     45   1.7  christos #include <stdarg.h>
     46  1.18     jwise #include <stdio.h>
     47  1.23       cgd #include <stdlib.h>
     48  1.22    itojun #include <string.h>
     49  1.40  dholland #include <unistd.h>
     50  1.35  dholland #include "array.h"
     51  1.20     jwise #include "extern.h"
     52  1.18     jwise #include "player.h"
     53  1.20     jwise #include "display.h"
     54   1.6       cgd 
     55  1.35  dholland /*
     56  1.35  dholland  * Use values above KEY_MAX for custom keycodes. (blymn@ says this is ok)
     57  1.35  dholland  */
     58  1.35  dholland #define KEY_ESC(ch) (KEY_MAX+10+ch)
     59  1.35  dholland 
     60   1.1       cgd 
     61   1.1       cgd /*
     62   1.1       cgd  * Display interface
     63   1.1       cgd  */
     64   1.1       cgd 
     65  1.35  dholland static void draw_view(void);
     66  1.35  dholland static void draw_turn(void);
     67  1.35  dholland static void draw_stat(void);
     68  1.35  dholland static void draw_slot(void);
     69  1.35  dholland static void draw_board(void);
     70  1.35  dholland 
     71  1.35  dholland static struct stringarray *sc_lines;
     72  1.35  dholland static unsigned sc_scrollup;
     73  1.35  dholland static bool sc_hasprompt;
     74  1.35  dholland static bool sc_hideprompt;
     75  1.11       jsm static const char *sc_prompt;
     76  1.11       jsm static const char *sc_buf;
     77  1.13       jsm 
     78  1.33  dholland static WINDOW *view_w;
     79  1.35  dholland static WINDOW *turn_w;
     80  1.35  dholland static WINDOW *stat_w;
     81  1.33  dholland static WINDOW *slot_w;
     82  1.33  dholland static WINDOW *scroll_w;
     83  1.35  dholland 
     84  1.35  dholland static bool obp[3];
     85  1.35  dholland static bool dbp[3];
     86  1.13       jsm 
     87  1.21     jwise int done_curses;
     88  1.40  dholland static bool ingame;
     89  1.21     jwise int loaded, fired, changed, repaired;
     90  1.21     jwise int dont_adjust;
     91  1.38  dholland static int viewrow, viewcol;
     92  1.13       jsm char movebuf[sizeof SHIP(0)->file->movebuf];
     93  1.13       jsm int player;
     94  1.13       jsm struct ship *ms;		/* memorial structure, &cc->ship[player] */
     95  1.13       jsm struct File *mf;		/* ms->file */
     96  1.13       jsm struct shipspecs *mc;		/* ms->specs */
     97   1.1       cgd 
     98  1.35  dholland ////////////////////////////////////////////////////////////
     99  1.35  dholland // overall initialization
    100  1.35  dholland 
    101  1.35  dholland static
    102  1.35  dholland void
    103  1.35  dholland define_esc_key(int ch)
    104  1.35  dholland {
    105  1.35  dholland 	char seq[3] = { '\x1b', ch, 0 };
    106  1.35  dholland 
    107  1.35  dholland 	define_key(seq, KEY_ESC(ch));
    108  1.35  dholland }
    109  1.35  dholland 
    110   1.7  christos void
    111  1.16     jwise initscreen(void)
    112   1.1       cgd {
    113  1.35  dholland 	int ch;
    114  1.35  dholland 
    115  1.35  dholland 	sc_lines = stringarray_create();
    116  1.35  dholland 	if (sc_lines == NULL) {
    117  1.35  dholland 		err(1, "malloc");
    118  1.35  dholland 	}
    119  1.35  dholland 
    120  1.33  dholland 	if (signal(SIGTSTP, SIG_DFL) == SIG_ERR) {
    121  1.33  dholland 		err(1, "signal(SIGTSTP)");
    122  1.33  dholland 	}
    123  1.33  dholland 
    124  1.33  dholland 	if (initscr() == NULL) {
    125  1.29  dholland 		errx(1, "Can't sail on this terminal.");
    126  1.14       jsm 	}
    127  1.33  dholland 	if (STAT_R >= COLS || SCROLL_Y <= 0) {
    128  1.33  dholland 		errx(1, "Window/terminal not large enough.");
    129  1.33  dholland 	}
    130  1.33  dholland 
    131   1.1       cgd 	view_w = newwin(VIEW_Y, VIEW_X, VIEW_T, VIEW_L);
    132   1.1       cgd 	slot_w = newwin(SLOT_Y, SLOT_X, SLOT_T, SLOT_L);
    133   1.1       cgd 	scroll_w = newwin(SCROLL_Y, SCROLL_X, SCROLL_T, SCROLL_L);
    134   1.1       cgd 	stat_w = newwin(STAT_Y, STAT_X, STAT_T, STAT_L);
    135   1.1       cgd 	turn_w = newwin(TURN_Y, TURN_X, TURN_T, TURN_L);
    136  1.33  dholland 
    137  1.33  dholland 	if (view_w == NULL ||
    138  1.33  dholland 	    slot_w == NULL ||
    139  1.33  dholland 	    scroll_w == NULL ||
    140  1.33  dholland 	    stat_w == NULL ||
    141  1.33  dholland 	    turn_w == NULL) {
    142  1.33  dholland 		endwin();
    143  1.33  dholland 		errx(1, "Curses initialization failed.");
    144  1.33  dholland 	}
    145  1.33  dholland 
    146  1.16     jwise 	leaveok(view_w, 1);
    147  1.16     jwise 	leaveok(slot_w, 1);
    148  1.16     jwise 	leaveok(stat_w, 1);
    149  1.16     jwise 	leaveok(turn_w, 1);
    150   1.1       cgd 	noecho();
    151  1.26     blymn 	cbreak();
    152  1.33  dholland 
    153  1.35  dholland 	/*
    154  1.35  dholland 	 * Define esc-x keys
    155  1.35  dholland 	 */
    156  1.40  dholland #if 0
    157  1.35  dholland 	for (ch = 0; ch < 127; ch++) {
    158  1.40  dholland 		if (ch != '[' && ch != 'O') {
    159  1.39  dholland 			define_esc_key(ch);
    160  1.39  dholland 		}
    161  1.35  dholland 	}
    162  1.40  dholland #else
    163  1.40  dholland 	(void)ch;
    164  1.40  dholland 	(void)define_esc_key;
    165  1.40  dholland #endif
    166  1.40  dholland 
    167  1.40  dholland 	keypad(stdscr, 1);
    168  1.40  dholland 	keypad(view_w, 1);
    169  1.40  dholland 	keypad(slot_w, 1);
    170  1.40  dholland 	keypad(scroll_w, 1);
    171  1.40  dholland 	keypad(stat_w, 1);
    172  1.40  dholland 	keypad(turn_w, 1);
    173  1.35  dholland 
    174  1.33  dholland 	done_curses++;
    175   1.1       cgd }
    176   1.1       cgd 
    177   1.7  christos void
    178  1.16     jwise cleanupscreen(void)
    179   1.1       cgd {
    180   1.1       cgd 	/* alarm already turned off */
    181   1.1       cgd 	if (done_curses) {
    182  1.40  dholland 		if (ingame) {
    183  1.40  dholland 			wmove(scroll_w, SCROLL_Y - 1, 0);
    184  1.40  dholland 			wclrtoeol(scroll_w);
    185  1.40  dholland 			display_redraw();
    186  1.40  dholland 		} else {
    187  1.40  dholland 			move(LINES-1, 0);
    188  1.40  dholland 			clrtoeol();
    189  1.40  dholland 		}
    190   1.1       cgd 		endwin();
    191   1.1       cgd 	}
    192   1.1       cgd }
    193   1.1       cgd 
    194  1.35  dholland ////////////////////////////////////////////////////////////
    195  1.40  dholland // curses utility functions
    196  1.40  dholland 
    197  1.40  dholland /*
    198  1.40  dholland  * fill to eol with spaces
    199  1.40  dholland  * (useful with A_REVERSE since cleartoeol() does not clear to reversed)
    200  1.40  dholland  */
    201  1.40  dholland static void
    202  1.40  dholland filltoeol(void)
    203  1.40  dholland {
    204  1.40  dholland 	int x;
    205  1.40  dholland 
    206  1.40  dholland 	for (x = getcurx(stdscr); x < COLS; x++) {
    207  1.40  dholland 		addch(' ');
    208  1.40  dholland 	}
    209  1.40  dholland }
    210  1.40  dholland 
    211  1.40  dholland /*
    212  1.40  dholland  * Add a maybe-selected string.
    213  1.40  dholland  *
    214  1.40  dholland  * Place strings starting at (Y0, X0); this is string ITEM; CURITEM
    215  1.40  dholland  * is the selected one; WIDTH is the total width. STR is the string.
    216  1.40  dholland  */
    217  1.40  dholland static void
    218  1.40  dholland mvaddselstr(int y, int x0, int item, int curitem,
    219  1.40  dholland 	    size_t width, const char *str)
    220  1.40  dholland {
    221  1.40  dholland 	size_t i, len;
    222  1.40  dholland 
    223  1.40  dholland 	len = strlen(str);
    224  1.40  dholland 
    225  1.40  dholland 	move(y, x0);
    226  1.40  dholland 	if (curitem == item) {
    227  1.40  dholland 		attron(A_REVERSE);
    228  1.40  dholland 	}
    229  1.40  dholland 	addstr(str);
    230  1.40  dholland 	if (curitem == item) {
    231  1.40  dholland 		for (i=len; i<width; i++) {
    232  1.40  dholland 			addch(' ');
    233  1.40  dholland 		}
    234  1.40  dholland 		attroff(A_REVERSE);
    235  1.40  dholland 	}
    236  1.40  dholland }
    237  1.40  dholland 
    238  1.40  dholland /*
    239  1.40  dholland  * Likewise but a printf.
    240  1.40  dholland  */
    241  1.42  dholland static void __printflike(6, 7)
    242  1.40  dholland mvselprintw(int y, int x0, int item, int curitem,
    243  1.40  dholland 	    size_t width, const char *fmt, ...)
    244  1.40  dholland {
    245  1.40  dholland 	va_list ap;
    246  1.40  dholland 	size_t x;
    247  1.40  dholland 
    248  1.40  dholland 	move(y, x0);
    249  1.40  dholland 	if (curitem == item) {
    250  1.40  dholland 		attron(A_REVERSE);
    251  1.40  dholland 	}
    252  1.40  dholland 	va_start(ap, fmt);
    253  1.40  dholland 	vwprintw(stdscr, fmt, ap);
    254  1.40  dholland 	va_end(ap);
    255  1.40  dholland 	if (curitem == item) {
    256  1.40  dholland 		for (x = getcurx(stdscr); x < x0 + width; x++) {
    257  1.40  dholland 			addch(' ');
    258  1.40  dholland 		}
    259  1.40  dholland 		attroff(A_REVERSE);
    260  1.40  dholland 	}
    261  1.40  dholland }
    262  1.40  dholland 
    263  1.40  dholland /*
    264  1.40  dholland  * Move up by 1, scrolling if needed.
    265  1.40  dholland  */
    266  1.40  dholland static void
    267  1.40  dholland up(int *posp, int *scrollp)
    268  1.40  dholland {
    269  1.40  dholland 	if (*posp > 0) {
    270  1.40  dholland 		(*posp)--;
    271  1.40  dholland 	}
    272  1.40  dholland 	if (scrollp != NULL) {
    273  1.40  dholland 		if (*posp < *scrollp) {
    274  1.40  dholland 			*scrollp = *posp;
    275  1.40  dholland 		}
    276  1.40  dholland 	}
    277  1.40  dholland }
    278  1.40  dholland 
    279  1.40  dholland /*
    280  1.40  dholland  * Move down by 1, scrolling if needed. MAX is the total number of
    281  1.40  dholland  * items; VISIBLE is the number that can be visible at once.
    282  1.40  dholland  */
    283  1.40  dholland static void
    284  1.40  dholland down(int *posp, int *scrollp, int max, int visible)
    285  1.40  dholland {
    286  1.40  dholland 	if (max > 0 && *posp < max - 1) {
    287  1.40  dholland 		(*posp)++;
    288  1.40  dholland 	}
    289  1.40  dholland 	if (scrollp != NULL) {
    290  1.40  dholland 		if (*posp > *scrollp + visible - 1) {
    291  1.40  dholland 			*scrollp = *posp - visible + 1;
    292  1.40  dholland 		}
    293  1.40  dholland 	}
    294  1.40  dholland }
    295  1.40  dholland 
    296  1.40  dholland /*
    297  1.40  dholland  * Complain briefly.
    298  1.40  dholland  */
    299  1.42  dholland static void __printflike(3, 4)
    300  1.40  dholland oops(int y, int x, const char *fmt, ...)
    301  1.40  dholland {
    302  1.40  dholland 	int oy, ox;
    303  1.40  dholland 	va_list ap;
    304  1.40  dholland 
    305  1.40  dholland 	oy = getcury(stdscr);
    306  1.40  dholland 	ox = getcurx(stdscr);
    307  1.40  dholland 	move(y, x);
    308  1.40  dholland 	va_start(ap, fmt);
    309  1.40  dholland 	vwprintw(stdscr, fmt, ap);
    310  1.40  dholland 	va_end(ap);
    311  1.40  dholland 	move(oy, ox);
    312  1.40  dholland 	wrefresh(stdscr);
    313  1.40  dholland 	sleep(1);
    314  1.40  dholland }
    315  1.40  dholland 
    316  1.40  dholland ////////////////////////////////////////////////////////////
    317  1.35  dholland // scrolling message area
    318  1.35  dholland 
    319  1.35  dholland static void
    320  1.35  dholland scrollarea_add(const char *text)
    321  1.35  dholland {
    322  1.35  dholland 	char *copy;
    323  1.35  dholland 	int errsave;
    324  1.35  dholland 
    325  1.35  dholland 	copy = strdup(text);
    326  1.35  dholland 	if (copy == NULL) {
    327  1.35  dholland 		goto nomem;
    328  1.35  dholland 	}
    329  1.35  dholland 	if (stringarray_add(sc_lines, copy, NULL)) {
    330  1.35  dholland 		goto nomem;
    331  1.35  dholland 	}
    332  1.35  dholland 	return;
    333  1.35  dholland 
    334  1.35  dholland nomem:
    335  1.35  dholland 	/*
    336  1.35  dholland 	 * XXX this should use leave(), but that won't
    337  1.35  dholland 	 * currently work right.
    338  1.35  dholland 	 */
    339  1.35  dholland 	errsave = errno;
    340  1.35  dholland #if 0
    341  1.35  dholland 	leave(LEAVE_MALLOC);
    342  1.35  dholland #else
    343  1.35  dholland 	cleanupscreen();
    344  1.35  dholland 	sync_close(!hasdriver);
    345  1.35  dholland 	errno = errsave;
    346  1.35  dholland 	err(1, "malloc");
    347  1.35  dholland #endif
    348  1.35  dholland }
    349  1.35  dholland 
    350  1.35  dholland static void
    351  1.35  dholland draw_scroll(void)
    352  1.35  dholland {
    353  1.35  dholland 	unsigned total_lines;
    354  1.35  dholland 	unsigned visible_lines;
    355  1.35  dholland 	unsigned index_of_top;
    356  1.35  dholland 	unsigned index_of_y;
    357  1.35  dholland 	unsigned y;
    358  1.35  dholland 	unsigned cursorx;
    359  1.35  dholland 
    360  1.35  dholland 	werase(scroll_w);
    361  1.35  dholland 
    362  1.37  dholland 	/* XXX: SCROLL_Y and whatnot should be unsigned too */
    363  1.35  dholland 	visible_lines = SCROLL_Y - 1;
    364  1.35  dholland 
    365  1.35  dholland 	total_lines = stringarray_num(sc_lines);
    366  1.35  dholland 	if (total_lines > visible_lines) {
    367  1.35  dholland 		index_of_top = total_lines - visible_lines;
    368  1.35  dholland 	} else {
    369  1.35  dholland 		index_of_top = 0;
    370  1.35  dholland 	}
    371  1.35  dholland 	if (index_of_top < sc_scrollup) {
    372  1.35  dholland 		index_of_top = 0;
    373  1.35  dholland 	} else {
    374  1.35  dholland 		index_of_top -= sc_scrollup;
    375  1.35  dholland 	}
    376  1.35  dholland 
    377  1.37  dholland 	for (y = 0; y < visible_lines; y++) {
    378  1.35  dholland 		index_of_y = index_of_top + y;
    379  1.35  dholland 		if (index_of_y >= total_lines) {
    380  1.35  dholland 			break;
    381  1.35  dholland 		}
    382  1.35  dholland 		wmove(scroll_w, y, 0);
    383  1.35  dholland 		waddstr(scroll_w, stringarray_get(sc_lines, index_of_y));
    384  1.35  dholland 	}
    385  1.35  dholland 	if (sc_hasprompt && !sc_hideprompt) {
    386  1.35  dholland 		wmove(scroll_w, SCROLL_Y-1, 0);
    387  1.35  dholland 		waddstr(scroll_w, sc_prompt);
    388  1.35  dholland 		waddstr(scroll_w, sc_buf);
    389  1.35  dholland 		cursorx = strlen(sc_prompt) + strlen(sc_buf);
    390  1.35  dholland 		wmove(scroll_w, SCROLL_Y-1, cursorx);
    391  1.35  dholland 	}
    392  1.35  dholland 	else {
    393  1.35  dholland 		wmove(scroll_w, SCROLL_Y-1, 0);
    394  1.35  dholland 	}
    395  1.35  dholland }
    396  1.35  dholland 
    397   1.1       cgd /*VARARGS2*/
    398   1.7  christos void
    399   1.7  christos Signal(const char *fmt, struct ship *ship, ...)
    400   1.1       cgd {
    401   1.7  christos 	va_list ap;
    402   1.7  christos 	char format[BUFSIZ];
    403  1.35  dholland 	char buf[BUFSIZ];
    404   1.7  christos 
    405   1.1       cgd 	if (!done_curses)
    406   1.1       cgd 		return;
    407  1.25       wiz 	va_start(ap, ship);
    408  1.35  dholland 	if (*fmt == '\a') {
    409  1.35  dholland 		beep();
    410  1.35  dholland 		fmt++;
    411  1.35  dholland 	}
    412   1.7  christos 	fmtship(format, sizeof(format), fmt, ship);
    413  1.35  dholland 	vsnprintf(buf, sizeof(buf), format, ap);
    414   1.7  christos 	va_end(ap);
    415  1.35  dholland 	scrollarea_add(buf);
    416   1.7  christos }
    417   1.7  christos 
    418   1.7  christos /*VARARGS2*/
    419   1.7  christos void
    420   1.7  christos Msg(const char *fmt, ...)
    421   1.7  christos {
    422   1.7  christos 	va_list ap;
    423  1.35  dholland 	char buf[BUFSIZ];
    424   1.7  christos 
    425   1.7  christos 	if (!done_curses)
    426   1.7  christos 		return;
    427  1.25       wiz 	va_start(ap, fmt);
    428  1.35  dholland 	if (*fmt == '\a') {
    429  1.35  dholland 		beep();
    430  1.35  dholland 		fmt++;
    431  1.35  dholland 	}
    432  1.35  dholland 	vsnprintf(buf, sizeof(buf), fmt, ap);
    433   1.7  christos 	va_end(ap);
    434  1.35  dholland 	scrollarea_add(buf);
    435   1.1       cgd }
    436   1.1       cgd 
    437  1.38  dholland static void
    438  1.17     jwise prompt(const char *p, struct ship *ship)
    439   1.1       cgd {
    440   1.8  christos 	static char buf[BUFSIZ];
    441   1.1       cgd 
    442   1.8  christos 	fmtship(buf, sizeof(buf), p, ship);
    443   1.8  christos 	sc_prompt = buf;
    444   1.1       cgd 	sc_buf = "";
    445  1.35  dholland 	sc_hasprompt = true;
    446   1.1       cgd }
    447   1.1       cgd 
    448  1.17     jwise static void
    449  1.35  dholland endprompt(void)
    450   1.1       cgd {
    451  1.35  dholland 	sc_prompt = NULL;
    452  1.35  dholland 	sc_buf = NULL;
    453  1.35  dholland 	sc_hasprompt = false;
    454   1.1       cgd }
    455   1.1       cgd 
    456  1.34  dholland /*
    457  1.34  dholland  * Next two functions called from newturn() to poke display. Shouldn't
    458  1.34  dholland  * exist... XXX
    459  1.34  dholland  */
    460  1.34  dholland 
    461  1.34  dholland void
    462  1.34  dholland display_hide_prompt(void)
    463  1.34  dholland {
    464  1.35  dholland 	sc_hideprompt = true;
    465  1.35  dholland 	draw_scroll();
    466  1.35  dholland 	wrefresh(scroll_w);
    467  1.34  dholland }
    468  1.34  dholland 
    469  1.34  dholland void
    470  1.34  dholland display_reshow_prompt(void)
    471  1.34  dholland {
    472  1.35  dholland 	sc_hideprompt = false;
    473  1.35  dholland 	draw_scroll();
    474  1.35  dholland 	wrefresh(scroll_w);
    475  1.34  dholland }
    476  1.34  dholland 
    477  1.34  dholland 
    478   1.7  christos int
    479  1.16     jwise sgetch(const char *p, struct ship *ship, int flag)
    480   1.1       cgd {
    481   1.7  christos 	int c;
    482  1.35  dholland 	char input[2];
    483  1.35  dholland 
    484   1.1       cgd 	prompt(p, ship);
    485  1.35  dholland 	input[0] = '\0';
    486  1.35  dholland 	input[1] = '\0';
    487  1.35  dholland 	sc_buf = input;
    488   1.1       cgd 	blockalarm();
    489  1.35  dholland 	draw_scroll();
    490  1.16     jwise 	wrefresh(scroll_w);
    491  1.35  dholland 	fflush(stdout);
    492   1.1       cgd 	unblockalarm();
    493   1.1       cgd 	while ((c = wgetch(scroll_w)) == EOF)
    494   1.1       cgd 		;
    495  1.35  dholland 	if (flag && c >= ' ' && c < 0x7f) {
    496  1.35  dholland 		blockalarm();
    497  1.35  dholland 		input[0] = c;
    498  1.35  dholland 		draw_scroll();
    499  1.35  dholland 		wrefresh(scroll_w);
    500  1.35  dholland 		fflush(stdout);
    501  1.35  dholland 		unblockalarm();
    502  1.35  dholland 	}
    503  1.35  dholland 	endprompt();
    504   1.1       cgd 	return c;
    505   1.1       cgd }
    506   1.1       cgd 
    507   1.7  christos void
    508  1.16     jwise sgetstr(const char *pr, char *buf, int n)
    509   1.1       cgd {
    510   1.7  christos 	int c;
    511   1.7  christos 	char *p = buf;
    512   1.1       cgd 
    513   1.1       cgd 	prompt(pr, (struct ship *)0);
    514   1.1       cgd 	sc_buf = buf;
    515   1.1       cgd 	for (;;) {
    516   1.1       cgd 		*p = 0;
    517   1.1       cgd 		blockalarm();
    518  1.35  dholland 		draw_scroll();
    519  1.16     jwise 		wrefresh(scroll_w);
    520  1.35  dholland 		fflush(stdout);
    521   1.1       cgd 		unblockalarm();
    522   1.1       cgd 		while ((c = wgetch(scroll_w)) == EOF)
    523   1.1       cgd 			;
    524   1.1       cgd 		switch (c) {
    525   1.1       cgd 		case '\n':
    526   1.1       cgd 		case '\r':
    527  1.35  dholland 			endprompt();
    528   1.1       cgd 			return;
    529   1.1       cgd 		case '\b':
    530   1.1       cgd 			if (p > buf) {
    531  1.35  dholland 				/*waddstr(scroll_w, "\b \b");*/
    532   1.1       cgd 				p--;
    533   1.1       cgd 			}
    534   1.1       cgd 			break;
    535   1.1       cgd 		default:
    536   1.1       cgd 			if (c >= ' ' && c < 0x7f && p < buf + n - 1) {
    537   1.1       cgd 				*p++ = c;
    538  1.35  dholland 				/*waddch(scroll_w, c);*/
    539   1.1       cgd 			} else
    540  1.35  dholland 				beep();
    541   1.1       cgd 		}
    542   1.1       cgd 	}
    543   1.1       cgd }
    544   1.1       cgd 
    545  1.35  dholland ////////////////////////////////////////////////////////////
    546  1.35  dholland // drawing of other panes
    547  1.35  dholland 
    548  1.35  dholland void
    549  1.35  dholland display_force_full_redraw(void)
    550  1.35  dholland {
    551  1.35  dholland 	clear();
    552  1.35  dholland }
    553  1.35  dholland 
    554   1.7  christos void
    555  1.35  dholland display_redraw(void)
    556   1.1       cgd {
    557  1.35  dholland 	draw_board();
    558   1.1       cgd 	draw_view();
    559   1.1       cgd 	draw_turn();
    560   1.1       cgd 	draw_stat();
    561   1.1       cgd 	draw_slot();
    562  1.35  dholland 	draw_scroll();
    563  1.35  dholland 	/* move the cursor */
    564  1.35  dholland 	wrefresh(scroll_w);
    565  1.35  dholland 	/* paranoia */
    566  1.35  dholland 	fflush(stdout);
    567   1.1       cgd }
    568   1.1       cgd 
    569  1.35  dholland static void
    570  1.16     jwise draw_view(void)
    571   1.1       cgd {
    572   1.7  christos 	struct ship *sp;
    573   1.1       cgd 
    574  1.16     jwise 	werase(view_w);
    575   1.1       cgd 	foreachship(sp) {
    576   1.1       cgd 		if (sp->file->dir
    577   1.1       cgd 		    && sp->file->row > viewrow
    578   1.1       cgd 		    && sp->file->row < viewrow + VIEW_Y
    579   1.1       cgd 		    && sp->file->col > viewcol
    580   1.1       cgd 		    && sp->file->col < viewcol + VIEW_X) {
    581  1.16     jwise 			wmove(view_w, sp->file->row - viewrow,
    582   1.1       cgd 				sp->file->col - viewcol);
    583  1.16     jwise 			waddch(view_w, colours(sp));
    584  1.16     jwise 			wmove(view_w,
    585   1.1       cgd 				sternrow(sp) - viewrow,
    586   1.1       cgd 				sterncol(sp) - viewcol);
    587  1.16     jwise 			waddch(view_w, sterncolour(sp));
    588   1.1       cgd 		}
    589   1.1       cgd 	}
    590  1.16     jwise 	wrefresh(view_w);
    591   1.1       cgd }
    592   1.1       cgd 
    593  1.35  dholland static void
    594  1.16     jwise draw_turn(void)
    595   1.1       cgd {
    596  1.16     jwise 	wmove(turn_w, 0, 0);
    597  1.16     jwise 	wprintw(turn_w, "%cTurn %d", dont_adjust?'*':'-', turn);
    598  1.16     jwise 	wrefresh(turn_w);
    599   1.1       cgd }
    600   1.1       cgd 
    601  1.35  dholland static void
    602  1.16     jwise draw_stat(void)
    603   1.1       cgd {
    604  1.16     jwise 	wmove(stat_w, STAT_1, 0);
    605  1.16     jwise 	wprintw(stat_w, "Points  %3d\n", mf->points);
    606  1.16     jwise 	wprintw(stat_w, "Fouls    %2d\n", fouled(ms));
    607  1.16     jwise 	wprintw(stat_w, "Grapples %2d\n", grappled(ms));
    608   1.1       cgd 
    609  1.16     jwise 	wmove(stat_w, STAT_2, 0);
    610  1.16     jwise 	wprintw(stat_w, "    0 %c(%c)\n",
    611   1.1       cgd 		maxmove(ms, winddir + 3, -1) + '0',
    612   1.1       cgd 		maxmove(ms, winddir + 3, 1) + '0');
    613  1.16     jwise 	waddstr(stat_w, "   \\|/\n");
    614  1.16     jwise 	wprintw(stat_w, "   -^-%c(%c)\n",
    615   1.1       cgd 		maxmove(ms, winddir + 2, -1) + '0',
    616   1.1       cgd 		maxmove(ms, winddir + 2, 1) + '0');
    617  1.16     jwise 	waddstr(stat_w, "   /|\\\n");
    618  1.16     jwise 	wprintw(stat_w, "    | %c(%c)\n",
    619   1.1       cgd 		maxmove(ms, winddir + 1, -1) + '0',
    620   1.1       cgd 		maxmove(ms, winddir + 1, 1) + '0');
    621  1.16     jwise 	wprintw(stat_w, "   %c(%c)\n",
    622   1.1       cgd 		maxmove(ms, winddir, -1) + '0',
    623   1.1       cgd 		maxmove(ms, winddir, 1) + '0');
    624   1.1       cgd 
    625  1.16     jwise 	wmove(stat_w, STAT_3, 0);
    626  1.16     jwise 	wprintw(stat_w, "Load  %c%c %c%c\n",
    627   1.1       cgd 		loadname[mf->loadL], readyname(mf->readyL),
    628   1.1       cgd 		loadname[mf->loadR], readyname(mf->readyR));
    629  1.16     jwise 	wprintw(stat_w, "Hull %2d\n", mc->hull);
    630  1.16     jwise 	wprintw(stat_w, "Crew %2d %2d %2d\n",
    631   1.1       cgd 		mc->crew1, mc->crew2, mc->crew3);
    632  1.16     jwise 	wprintw(stat_w, "Guns %2d %2d\n", mc->gunL, mc->gunR);
    633  1.16     jwise 	wprintw(stat_w, "Carr %2d %2d\n", mc->carL, mc->carR);
    634  1.16     jwise 	wprintw(stat_w, "Rigg %d %d %d ", mc->rig1, mc->rig2, mc->rig3);
    635   1.1       cgd 	if (mc->rig4 < 0)
    636  1.16     jwise 		waddch(stat_w, '-');
    637   1.1       cgd 	else
    638  1.16     jwise 		wprintw(stat_w, "%d", mc->rig4);
    639  1.16     jwise 	wrefresh(stat_w);
    640   1.1       cgd }
    641   1.1       cgd 
    642   1.7  christos void
    643  1.16     jwise draw_slot(void)
    644   1.1       cgd {
    645  1.35  dholland 	int i;
    646  1.35  dholland 
    647   1.1       cgd 	if (!boarding(ms, 0)) {
    648  1.16     jwise 		mvwaddstr(slot_w, 0, 0, "   ");
    649  1.16     jwise 		mvwaddstr(slot_w, 1, 0, "   ");
    650  1.35  dholland 	} else {
    651  1.35  dholland 		wmove(slot_w, 0, 0);
    652  1.35  dholland 		for (i = 0; i < 3; i++) {
    653  1.35  dholland 			waddch(slot_w, obp[i] ? '1'+i : ' ');
    654  1.35  dholland 		}
    655  1.16     jwise 		mvwaddstr(slot_w, 1, 0, "OBP");
    656  1.35  dholland 	}
    657   1.1       cgd 	if (!boarding(ms, 1)) {
    658  1.16     jwise 		mvwaddstr(slot_w, 2, 0, "   ");
    659  1.16     jwise 		mvwaddstr(slot_w, 3, 0, "   ");
    660  1.35  dholland 	} else {
    661  1.35  dholland 		wmove(slot_w, 2, 0);
    662  1.35  dholland 		for (i = 0; i < 3; i++) {
    663  1.35  dholland 			waddch(slot_w, dbp[i] ? '1'+i : ' ');
    664  1.35  dholland 		}
    665  1.16     jwise 		mvwaddstr(slot_w, 3, 0, "DBP");
    666  1.35  dholland 	}
    667   1.1       cgd 
    668  1.16     jwise 	wmove(slot_w, SLOT_Y-4, 0);
    669   1.1       cgd 	if (mf->RH)
    670  1.16     jwise 		wprintw(slot_w, "%dRH", mf->RH);
    671   1.1       cgd 	else
    672  1.16     jwise 		waddstr(slot_w, "   ");
    673  1.16     jwise 	wmove(slot_w, SLOT_Y-3, 0);
    674   1.1       cgd 	if (mf->RG)
    675  1.16     jwise 		wprintw(slot_w, "%dRG", mf->RG);
    676   1.1       cgd 	else
    677  1.16     jwise 		waddstr(slot_w, "   ");
    678  1.16     jwise 	wmove(slot_w, SLOT_Y-2, 0);
    679   1.1       cgd 	if (mf->RR)
    680  1.16     jwise 		wprintw(slot_w, "%dRR", mf->RR);
    681   1.1       cgd 	else
    682  1.16     jwise 		waddstr(slot_w, "   ");
    683   1.1       cgd 
    684   1.1       cgd #define Y	(SLOT_Y/2)
    685  1.16     jwise 	wmove(slot_w, 7, 1);
    686  1.16     jwise 	wprintw(slot_w,"%d", windspeed);
    687  1.16     jwise 	mvwaddch(slot_w, Y, 0, ' ');
    688  1.16     jwise 	mvwaddch(slot_w, Y, 2, ' ');
    689  1.16     jwise 	mvwaddch(slot_w, Y-1, 0, ' ');
    690  1.16     jwise 	mvwaddch(slot_w, Y-1, 1, ' ');
    691  1.16     jwise 	mvwaddch(slot_w, Y-1, 2, ' ');
    692  1.16     jwise 	mvwaddch(slot_w, Y+1, 0, ' ');
    693  1.16     jwise 	mvwaddch(slot_w, Y+1, 1, ' ');
    694  1.16     jwise 	mvwaddch(slot_w, Y+1, 2, ' ');
    695  1.16     jwise 	wmove(slot_w, Y - dr[winddir], 1 - dc[winddir]);
    696   1.1       cgd 	switch (winddir) {
    697   1.1       cgd 	case 1:
    698   1.1       cgd 	case 5:
    699  1.16     jwise 		waddch(slot_w, '|');
    700   1.1       cgd 		break;
    701   1.1       cgd 	case 2:
    702   1.1       cgd 	case 6:
    703  1.16     jwise 		waddch(slot_w, '/');
    704   1.1       cgd 		break;
    705   1.1       cgd 	case 3:
    706   1.1       cgd 	case 7:
    707  1.16     jwise 		waddch(slot_w, '-');
    708   1.1       cgd 		break;
    709   1.1       cgd 	case 4:
    710   1.1       cgd 	case 8:
    711  1.16     jwise 		waddch(slot_w, '\\');
    712   1.1       cgd 		break;
    713   1.1       cgd 	}
    714  1.16     jwise 	mvwaddch(slot_w, Y + dr[winddir], 1 + dc[winddir], '+');
    715  1.16     jwise 	wrefresh(slot_w);
    716   1.1       cgd }
    717   1.1       cgd 
    718   1.7  christos void
    719  1.16     jwise draw_board(void)
    720   1.1       cgd {
    721   1.7  christos 	int n;
    722   1.1       cgd 
    723  1.35  dholland 	erase();
    724  1.16     jwise 	werase(view_w);
    725  1.16     jwise 	werase(slot_w);
    726  1.16     jwise 	werase(scroll_w);
    727  1.16     jwise 	werase(stat_w);
    728  1.16     jwise 	werase(turn_w);
    729   1.1       cgd 
    730  1.16     jwise 	move(BOX_T, BOX_L);
    731   1.1       cgd 	for (n = 0; n < BOX_X; n++)
    732  1.16     jwise 		addch('-');
    733  1.16     jwise 	move(BOX_B, BOX_L);
    734   1.1       cgd 	for (n = 0; n < BOX_X; n++)
    735  1.16     jwise 		addch('-');
    736   1.1       cgd 	for (n = BOX_T+1; n < BOX_B; n++) {
    737  1.16     jwise 		mvaddch(n, BOX_L, '|');
    738  1.16     jwise 		mvaddch(n, BOX_R, '|');
    739   1.1       cgd 	}
    740  1.16     jwise 	mvaddch(BOX_T, BOX_L, '+');
    741  1.16     jwise 	mvaddch(BOX_T, BOX_R, '+');
    742  1.16     jwise 	mvaddch(BOX_B, BOX_L, '+');
    743  1.16     jwise 	mvaddch(BOX_B, BOX_R, '+');
    744  1.16     jwise 	refresh();
    745   1.1       cgd 
    746  1.35  dholland #if 0
    747   1.1       cgd #define WSaIM "Wooden Ships & Iron Men"
    748  1.16     jwise 	wmove(view_w, 2, (VIEW_X - sizeof WSaIM - 1) / 2);
    749  1.16     jwise 	waddstr(view_w, WSaIM);
    750  1.16     jwise 	wmove(view_w, 4, (VIEW_X - strlen(cc->name)) / 2);
    751  1.16     jwise 	waddstr(view_w, cc->name);
    752  1.16     jwise 	wrefresh(view_w);
    753  1.35  dholland #endif
    754   1.1       cgd 
    755  1.16     jwise 	move(LINE_T, LINE_L);
    756  1.16     jwise 	printw("Class %d %s (%d guns) '%s' (%c%c)",
    757   1.1       cgd 		mc->class,
    758   1.1       cgd 		classname[mc->class],
    759   1.1       cgd 		mc->guns,
    760   1.1       cgd 		ms->shipname,
    761   1.1       cgd 		colours(ms),
    762   1.1       cgd 		sterncolour(ms));
    763  1.16     jwise 	refresh();
    764   1.1       cgd }
    765   1.1       cgd 
    766  1.33  dholland void
    767  1.35  dholland display_set_obp(int which, bool show)
    768  1.35  dholland {
    769  1.35  dholland 	obp[which] = show;
    770  1.35  dholland }
    771  1.35  dholland 
    772  1.35  dholland void
    773  1.35  dholland display_set_dbp(int which, bool show)
    774  1.33  dholland {
    775  1.35  dholland 	dbp[which] = show;
    776  1.33  dholland }
    777  1.33  dholland 
    778  1.35  dholland ////////////////////////////////////////////////////////////
    779  1.35  dholland // external actions on the display
    780  1.35  dholland 
    781  1.33  dholland void
    782  1.35  dholland display_scroll_pageup(void)
    783  1.33  dholland {
    784  1.35  dholland 	unsigned total_lines, visible_lines, limit;
    785  1.35  dholland 	unsigned pagesize = SCROLL_Y - 2;
    786  1.35  dholland 
    787  1.35  dholland 	total_lines = stringarray_num(sc_lines);
    788  1.35  dholland 	visible_lines = SCROLL_Y - 1;
    789  1.35  dholland 	limit = total_lines - visible_lines;
    790  1.35  dholland 
    791  1.35  dholland 	sc_scrollup += pagesize;
    792  1.35  dholland 	if (sc_scrollup > limit) {
    793  1.35  dholland 		sc_scrollup = limit;
    794  1.35  dholland 	}
    795  1.33  dholland }
    796  1.33  dholland 
    797  1.33  dholland void
    798  1.35  dholland display_scroll_pagedown(void)
    799  1.33  dholland {
    800  1.35  dholland 	unsigned pagesize = SCROLL_Y - 2;
    801  1.35  dholland 
    802  1.35  dholland 	if (sc_scrollup < pagesize) {
    803  1.35  dholland 		sc_scrollup = 0;
    804  1.35  dholland 	} else {
    805  1.35  dholland 		sc_scrollup -= pagesize;
    806  1.35  dholland 	}
    807  1.33  dholland }
    808  1.33  dholland 
    809   1.7  christos void
    810  1.16     jwise centerview(void)
    811   1.1       cgd {
    812   1.1       cgd 	viewrow = mf->row - VIEW_Y / 2;
    813   1.1       cgd 	viewcol = mf->col - VIEW_X / 2;
    814   1.1       cgd }
    815   1.1       cgd 
    816   1.7  christos void
    817  1.16     jwise upview(void)
    818   1.1       cgd {
    819   1.1       cgd 	viewrow -= VIEW_Y / 3;
    820   1.1       cgd }
    821   1.1       cgd 
    822   1.7  christos void
    823  1.16     jwise downview(void)
    824   1.1       cgd {
    825   1.1       cgd 	viewrow += VIEW_Y / 3;
    826   1.1       cgd }
    827   1.1       cgd 
    828   1.7  christos void
    829  1.16     jwise leftview(void)
    830   1.1       cgd {
    831   1.1       cgd 	viewcol -= VIEW_X / 5;
    832   1.1       cgd }
    833   1.1       cgd 
    834   1.7  christos void
    835  1.16     jwise rightview(void)
    836   1.1       cgd {
    837   1.1       cgd 	viewcol += VIEW_X / 5;
    838   1.1       cgd }
    839   1.1       cgd 
    840  1.34  dholland /* Called from newturn()... rename? */
    841  1.34  dholland void
    842  1.34  dholland display_adjust_view(void)
    843   1.1       cgd {
    844   1.1       cgd 	if (dont_adjust)
    845   1.1       cgd 		return;
    846   1.1       cgd 	if (mf->row < viewrow + VIEW_Y/4)
    847   1.1       cgd 		viewrow = mf->row - (VIEW_Y - VIEW_Y/4);
    848   1.1       cgd 	else if (mf->row > viewrow + (VIEW_Y - VIEW_Y/4))
    849   1.1       cgd 		viewrow = mf->row - VIEW_Y/4;
    850   1.1       cgd 	if (mf->col < viewcol + VIEW_X/8)
    851   1.1       cgd 		viewcol = mf->col - (VIEW_X - VIEW_X/8);
    852   1.1       cgd 	else if (mf->col > viewcol + (VIEW_X - VIEW_X/8))
    853   1.1       cgd 		viewcol = mf->col - VIEW_X/8;
    854   1.1       cgd }
    855  1.40  dholland 
    856  1.40  dholland ////////////////////////////////////////////////////////////
    857  1.40  dholland // starting game
    858  1.40  dholland 
    859  1.40  dholland static bool shipselected;
    860  1.40  dholland static int loadpos;
    861  1.40  dholland 
    862  1.40  dholland static int
    863  1.40  dholland nextload(int load)
    864  1.40  dholland {
    865  1.40  dholland 	switch (load) {
    866  1.40  dholland 	    case L_ROUND: return L_GRAPE;
    867  1.40  dholland 	    case L_GRAPE: return L_CHAIN;
    868  1.40  dholland 	    case L_CHAIN: return L_DOUBLE;
    869  1.40  dholland 	    case L_DOUBLE: return L_ROUND;
    870  1.40  dholland 	}
    871  1.40  dholland 	return L_ROUND;
    872  1.40  dholland }
    873  1.40  dholland 
    874  1.40  dholland static int
    875  1.40  dholland loadbychar(int ch)
    876  1.40  dholland {
    877  1.40  dholland 	switch (ch) {
    878  1.40  dholland 	    case 'r': return L_ROUND;
    879  1.40  dholland 	    case 'g': return L_GRAPE;
    880  1.40  dholland 	    case 'c': return L_CHAIN;
    881  1.40  dholland 	    case 'd': return L_DOUBLE;
    882  1.40  dholland 	}
    883  1.40  dholland 	return L_ROUND;
    884  1.40  dholland }
    885  1.40  dholland 
    886  1.40  dholland static const char *
    887  1.40  dholland loadstr(int load)
    888  1.40  dholland {
    889  1.40  dholland 	switch (load) {
    890  1.40  dholland 	    case L_ROUND: return "round";
    891  1.40  dholland 	    case L_GRAPE: return "grape";
    892  1.40  dholland 	    case L_CHAIN: return "chain";
    893  1.40  dholland 	    case L_DOUBLE: return "double";
    894  1.40  dholland 	}
    895  1.40  dholland 	return "???";
    896  1.40  dholland }
    897  1.40  dholland 
    898  1.40  dholland static void
    899  1.40  dholland displayshiplist(void)
    900  1.40  dholland {
    901  1.40  dholland 	struct ship *sp;
    902  1.40  dholland 	int which;
    903  1.40  dholland 
    904  1.40  dholland 	erase();
    905  1.40  dholland 
    906  1.40  dholland 	attron(A_BOLD);
    907  1.40  dholland 	mvaddstr(1, 4, cc->name);
    908  1.40  dholland 	attroff(A_BOLD);
    909  1.40  dholland 
    910  1.40  dholland 	which = 0;
    911  1.40  dholland 	foreachship(sp) {
    912  1.40  dholland 		mvselprintw(which + 3, 4, which, player, 60,
    913  1.40  dholland 			    "  %2d:  %-10s %-15s  (%-2d pts)   %s",
    914  1.40  dholland 			    sp->file->index,
    915  1.40  dholland 			    countryname[sp->nationality],
    916  1.40  dholland 			    sp->shipname,
    917  1.40  dholland 			    sp->specs->pts,
    918  1.40  dholland 			    saywhat(sp, 1));
    919  1.40  dholland 		which++;
    920  1.40  dholland 	}
    921  1.40  dholland 
    922  1.40  dholland 	if (!shipselected) {
    923  1.40  dholland 		mvaddstr(15, 4, "Choose your ship");
    924  1.40  dholland 		move(player + 3, 63);
    925  1.40  dholland 	} else {
    926  1.40  dholland 		mvselprintw(15, 4, 0, loadpos, 32,
    927  1.40  dholland 			    "Initial left broadside: %s", loadstr(mf->loadL));
    928  1.40  dholland 		mvselprintw(16, 4, 1, loadpos, 32,
    929  1.40  dholland 			    "Initial right broadside: %s", loadstr(mf->loadR));
    930  1.40  dholland 		mvselprintw(17, 4, 2, loadpos, 32, "Set sail");
    931  1.40  dholland 		move(loadpos+15, 35);
    932  1.40  dholland 	}
    933  1.40  dholland 
    934  1.40  dholland 	wrefresh(stdscr);
    935  1.40  dholland }
    936  1.40  dholland 
    937  1.40  dholland static int
    938  1.40  dholland pickship(void)
    939  1.40  dholland {
    940  1.40  dholland 	struct File *fp;
    941  1.40  dholland 	struct ship *sp;
    942  1.40  dholland 	bool done;
    943  1.40  dholland 	int ch;
    944  1.40  dholland 
    945  1.40  dholland 	for (;;) {
    946  1.40  dholland 		foreachship(sp)
    947  1.40  dholland 			if (sp->file->captain[0] == 0 && !sp->file->struck
    948  1.40  dholland 			    && sp->file->captured == 0)
    949  1.40  dholland 				break;
    950  1.40  dholland 		if (sp >= ls) {
    951  1.40  dholland 			return -1;
    952  1.40  dholland 		}
    953  1.40  dholland 		player = sp - SHIP(0);
    954  1.40  dholland 		if (randomize) {
    955  1.40  dholland 			/* nothing */
    956  1.40  dholland 		} else {
    957  1.40  dholland 			done = false;
    958  1.40  dholland 			while (!done) {
    959  1.40  dholland 				displayshiplist();
    960  1.40  dholland 
    961  1.40  dholland 				ch = getch();
    962  1.40  dholland 				switch (ch) {
    963  1.40  dholland 				    case 12 /*^L*/:
    964  1.40  dholland 					clear();
    965  1.40  dholland 					break;
    966  1.40  dholland 				    case '\r':
    967  1.40  dholland 				    case '\n':
    968  1.40  dholland 					done = true;
    969  1.40  dholland 					break;
    970  1.40  dholland 				    case 7 /*^G*/:
    971  1.40  dholland 				    case 8 /*^H*/:
    972  1.40  dholland 				    case 27 /*ESC*/:
    973  1.40  dholland 				    case 127 /*^?*/:
    974  1.40  dholland 					beep();
    975  1.40  dholland 					break;
    976  1.40  dholland 				    case 16 /*^P*/:
    977  1.40  dholland 				    case KEY_UP:
    978  1.40  dholland 					up(&player, NULL);
    979  1.40  dholland 					break;
    980  1.40  dholland 				    case 14 /*^N*/:
    981  1.40  dholland 				    case KEY_DOWN:
    982  1.40  dholland 					down(&player, NULL, cc->vessels,
    983  1.40  dholland 					     cc->vessels);
    984  1.40  dholland 					break;
    985  1.40  dholland 				    default:
    986  1.40  dholland 					beep();
    987  1.40  dholland 					break;
    988  1.40  dholland 				}
    989  1.40  dholland 			}
    990  1.40  dholland 		}
    991  1.40  dholland 		if (player < 0)
    992  1.40  dholland 			continue;
    993  1.40  dholland 		if (Sync() < 0)
    994  1.40  dholland 			leave(LEAVE_SYNC);
    995  1.40  dholland 		fp = SHIP(player)->file;
    996  1.40  dholland 		if (fp->captain[0] || fp->struck || fp->captured != 0)
    997  1.40  dholland 			oops(16, 4, "That ship is taken.");
    998  1.40  dholland 		else
    999  1.40  dholland 			break;
   1000  1.40  dholland 	}
   1001  1.40  dholland 	return 0;
   1002  1.40  dholland }
   1003  1.40  dholland 
   1004  1.40  dholland static void
   1005  1.40  dholland pickload(void)
   1006  1.40  dholland {
   1007  1.40  dholland 	bool done;
   1008  1.40  dholland 	int ch;
   1009  1.40  dholland 
   1010  1.40  dholland 	mf->loadL = L_ROUND;
   1011  1.40  dholland 	mf->loadR = L_ROUND;
   1012  1.40  dholland 
   1013  1.40  dholland 	loadpos = 0;
   1014  1.40  dholland 	done = false;
   1015  1.40  dholland 	while (!done) {
   1016  1.40  dholland 		displayshiplist();
   1017  1.40  dholland 
   1018  1.40  dholland 		ch = getch();
   1019  1.40  dholland 		switch (ch) {
   1020  1.40  dholland 		    case 12 /*^L*/:
   1021  1.40  dholland 			clear();
   1022  1.40  dholland 			break;
   1023  1.40  dholland 		    case 'r':
   1024  1.40  dholland 		    case 'g':
   1025  1.40  dholland 		    case 'c':
   1026  1.40  dholland 		    case 'd':
   1027  1.40  dholland 			switch (loadpos) {
   1028  1.40  dholland 			    case 0: mf->loadL = loadbychar(ch); break;
   1029  1.40  dholland 			    case 1: mf->loadR = loadbychar(ch); break;
   1030  1.40  dholland 			    case 2: beep(); break;
   1031  1.40  dholland 			}
   1032  1.40  dholland 			break;
   1033  1.40  dholland 		    case '\r':
   1034  1.40  dholland 		    case '\n':
   1035  1.40  dholland 			switch (loadpos) {
   1036  1.40  dholland 			    case 0: mf->loadL = nextload(mf->loadL); break;
   1037  1.40  dholland 			    case 1: mf->loadR = nextload(mf->loadR); break;
   1038  1.40  dholland 			    case 2: done = true; break;
   1039  1.40  dholland 			}
   1040  1.40  dholland 			break;
   1041  1.40  dholland 		    case 7 /*^G*/:
   1042  1.40  dholland 		    case 8 /*^H*/:
   1043  1.40  dholland 		    case 27 /*ESC*/:
   1044  1.40  dholland 		    case 127 /*^?*/:
   1045  1.40  dholland 			beep();
   1046  1.40  dholland 			break;
   1047  1.40  dholland 		    case 16 /*^P*/:
   1048  1.40  dholland 		    case KEY_UP:
   1049  1.40  dholland 			up(&loadpos, NULL);
   1050  1.40  dholland 			break;
   1051  1.40  dholland 		    case 14 /*^N*/:
   1052  1.40  dholland 		    case KEY_DOWN:
   1053  1.40  dholland 			down(&loadpos, NULL, 3, 3);
   1054  1.40  dholland 			break;
   1055  1.40  dholland 		    default:
   1056  1.40  dholland 			beep();
   1057  1.40  dholland 			break;
   1058  1.40  dholland 		}
   1059  1.40  dholland 	}
   1060  1.40  dholland 	mf->readyR = R_LOADED|R_INITIAL;
   1061  1.40  dholland 	mf->readyL = R_LOADED|R_INITIAL;
   1062  1.40  dholland }
   1063  1.40  dholland 
   1064  1.40  dholland static void
   1065  1.40  dholland startgame(void)
   1066  1.40  dholland {
   1067  1.40  dholland 
   1068  1.40  dholland 	ingame = true;
   1069  1.40  dholland 	shipselected = false;
   1070  1.40  dholland 
   1071  1.40  dholland 	pl_main_init();
   1072  1.40  dholland 
   1073  1.40  dholland 	hasdriver = sync_exists(game);
   1074  1.40  dholland 	if (sync_open() < 0) {
   1075  1.40  dholland 		oops(21, 10, "syncfile: %s", strerror(errno));
   1076  1.40  dholland 		pl_main_uninit();
   1077  1.40  dholland 		ingame = false;
   1078  1.40  dholland 		return;
   1079  1.40  dholland 	}
   1080  1.40  dholland 
   1081  1.40  dholland 	if (hasdriver) {
   1082  1.40  dholland 		mvaddstr(21, 10, "Synchronizing with the other players...");
   1083  1.40  dholland 		wrefresh(stdscr);
   1084  1.40  dholland 		fflush(stdout);
   1085  1.40  dholland 		if (Sync() < 0)
   1086  1.40  dholland 			leave(LEAVE_SYNC);
   1087  1.40  dholland 	} else {
   1088  1.40  dholland 		mvaddstr(21, 10, "Starting driver...");
   1089  1.40  dholland 		wrefresh(stdscr);
   1090  1.40  dholland 		fflush(stdout);
   1091  1.40  dholland 		startdriver();
   1092  1.40  dholland 	}
   1093  1.40  dholland 
   1094  1.40  dholland 	if (pickship() < 0) {
   1095  1.40  dholland 		oops(21, 10, "All ships taken in that scenario.");
   1096  1.40  dholland 		sync_close(0);
   1097  1.40  dholland 		people = 0;
   1098  1.40  dholland 		pl_main_uninit();
   1099  1.40  dholland 		ingame = false;
   1100  1.40  dholland 		return;
   1101  1.40  dholland 	}
   1102  1.40  dholland 	shipselected = true;
   1103  1.40  dholland 
   1104  1.40  dholland 	ms = SHIP(player);
   1105  1.40  dholland 	mf = ms->file;
   1106  1.40  dholland 	mc = ms->specs;
   1107  1.40  dholland 
   1108  1.40  dholland 	pickload();
   1109  1.40  dholland 
   1110  1.40  dholland 	pl_main();
   1111  1.40  dholland 	ingame = false;
   1112  1.40  dholland }
   1113  1.40  dholland 
   1114  1.40  dholland ////////////////////////////////////////////////////////////
   1115  1.40  dholland // scenario picker
   1116  1.40  dholland 
   1117  1.40  dholland static int pickerpos;
   1118  1.40  dholland static int pickerscroll;
   1119  1.40  dholland 
   1120  1.40  dholland static const char *
   1121  1.40  dholland absdirectionname(int dir)
   1122  1.40  dholland {
   1123  1.40  dholland 	switch (dir) {
   1124  1.40  dholland 	    case 1: return "South";
   1125  1.40  dholland 	    case 2: return "Southwest";
   1126  1.40  dholland 	    case 3: return "West";
   1127  1.40  dholland 	    case 4: return "Northwest";
   1128  1.40  dholland 	    case 5: return "North";
   1129  1.40  dholland 	    case 6: return "Northeast";
   1130  1.40  dholland 	    case 7: return "East";
   1131  1.40  dholland 	    case 8: return "Southeast";
   1132  1.40  dholland 	}
   1133  1.40  dholland 	return "?";
   1134  1.40  dholland }
   1135  1.40  dholland 
   1136  1.40  dholland static const char *
   1137  1.40  dholland windname(int wind)
   1138  1.40  dholland {
   1139  1.40  dholland 	switch (wind) {
   1140  1.40  dholland 	    case 0: return "calm";
   1141  1.40  dholland 	    case 1: return "light breeze";
   1142  1.40  dholland 	    case 2: return "moderate breeze";
   1143  1.40  dholland 	    case 3: return "fresh breeze";
   1144  1.40  dholland 	    case 4: return "strong breeze";
   1145  1.40  dholland 	    case 5: return "gale";
   1146  1.40  dholland 	    case 6: return "full gale";
   1147  1.40  dholland 	    case 7: return "hurricane";
   1148  1.40  dholland 	}
   1149  1.40  dholland 	return "???";
   1150  1.40  dholland }
   1151  1.40  dholland 
   1152  1.40  dholland static const char *
   1153  1.40  dholland nationalityname(int nationality)
   1154  1.40  dholland {
   1155  1.40  dholland 	switch (nationality) {
   1156  1.40  dholland 	    case N_A: return "a";
   1157  1.40  dholland 	    case N_B: return "b";
   1158  1.40  dholland 	    case N_S: return "s";
   1159  1.40  dholland 	    case N_F: return "f";
   1160  1.40  dholland 	    case N_J: return "j";
   1161  1.40  dholland 	    case N_D: return "d";
   1162  1.40  dholland 	    case N_K: return "k";
   1163  1.40  dholland 	    case N_O: return "o";
   1164  1.40  dholland 	}
   1165  1.40  dholland 	return "?";
   1166  1.40  dholland }
   1167  1.40  dholland 
   1168  1.40  dholland static void
   1169  1.40  dholland drawpicker(void)
   1170  1.40  dholland {
   1171  1.40  dholland 	int y, sc, i;
   1172  1.40  dholland 	struct ship *ship;
   1173  1.40  dholland 
   1174  1.40  dholland 	erase();
   1175  1.40  dholland 
   1176  1.40  dholland 	mvaddstr(0, 0, "## SHIPS  TITLE");
   1177  1.40  dholland 	for (y=1; y<LINES-11; y++) {
   1178  1.40  dholland 		sc = (y-1) + pickerscroll;
   1179  1.40  dholland 		if (sc < NSCENE) {
   1180  1.40  dholland 			mvselprintw(y, 0, sc, pickerpos, 56,
   1181  1.40  dholland 				    "%-2d %-5d  %s",
   1182  1.40  dholland 				    sc, scene[sc].vessels, scene[sc].name);
   1183  1.40  dholland 		}
   1184  1.40  dholland 	}
   1185  1.40  dholland 
   1186  1.40  dholland 	mvprintw(2, 60 + 2, "%s wind",
   1187  1.40  dholland 		 absdirectionname(scene[pickerpos].winddir));
   1188  1.40  dholland 	mvprintw(3, 60 + 2, "(%s)",
   1189  1.40  dholland 		 windname(scene[pickerpos].windspeed));
   1190  1.40  dholland 
   1191  1.40  dholland 	for (i=0; i<scene[pickerpos].vessels; i++) {
   1192  1.40  dholland 		ship = &scene[pickerpos].ship[i];
   1193  1.40  dholland 		mvprintw(LINES-10 + i, 0,
   1194  1.40  dholland 			 "(%s) %-16s %3d gun %s (%s crew) (%d pts)",
   1195  1.40  dholland 			 nationalityname(ship->nationality),
   1196  1.40  dholland 			 ship->shipname,
   1197  1.40  dholland 			 ship->specs->guns,
   1198  1.40  dholland 			 shortclassname[ship->specs->class],
   1199  1.40  dholland 			 qualname[ship->specs->qual],
   1200  1.40  dholland 			 ship->specs->pts);
   1201  1.40  dholland 	}
   1202  1.40  dholland 
   1203  1.40  dholland 	move(1 + pickerpos - pickerscroll, 55);
   1204  1.40  dholland 	wrefresh(stdscr);
   1205  1.40  dholland }
   1206  1.40  dholland 
   1207  1.40  dholland static int
   1208  1.40  dholland pickscenario(int initpos)
   1209  1.40  dholland {
   1210  1.40  dholland 	int ch;
   1211  1.40  dholland 
   1212  1.40  dholland 	pickerpos = initpos;
   1213  1.40  dholland 	if (pickerpos < 0) {
   1214  1.40  dholland 		pickerpos = 0;
   1215  1.40  dholland 	}
   1216  1.40  dholland 
   1217  1.40  dholland 	while (1) {
   1218  1.40  dholland 		drawpicker();
   1219  1.40  dholland 		ch = getch();
   1220  1.40  dholland 		switch (ch) {
   1221  1.40  dholland 		    case 12 /*^L*/:
   1222  1.40  dholland 			clear();
   1223  1.40  dholland 			break;
   1224  1.40  dholland 		    case '\r':
   1225  1.40  dholland 		    case '\n':
   1226  1.40  dholland 			return pickerpos;
   1227  1.40  dholland 		    case 7 /*^G*/:
   1228  1.40  dholland 		    case 8 /*^H*/:
   1229  1.40  dholland 		    case 27 /*ESC*/:
   1230  1.40  dholland 		    case 127 /*^?*/:
   1231  1.40  dholland 			return initpos;
   1232  1.40  dholland 		    case 16 /*^P*/:
   1233  1.40  dholland 		    case KEY_UP:
   1234  1.40  dholland 			up(&pickerpos, &pickerscroll);
   1235  1.40  dholland 			break;
   1236  1.40  dholland 		    case 14 /*^N*/:
   1237  1.40  dholland 		    case KEY_DOWN:
   1238  1.40  dholland 			down(&pickerpos, &pickerscroll, NSCENE, LINES-12);
   1239  1.40  dholland 			break;
   1240  1.40  dholland 		    default:
   1241  1.40  dholland 			beep();
   1242  1.40  dholland 			break;
   1243  1.40  dholland 		}
   1244  1.40  dholland 	}
   1245  1.40  dholland 	return pickerpos;
   1246  1.40  dholland }
   1247  1.40  dholland 
   1248  1.40  dholland ////////////////////////////////////////////////////////////
   1249  1.40  dholland // setup menus
   1250  1.40  dholland 
   1251  1.40  dholland #define MAINITEMS_NUM 5
   1252  1.40  dholland #define STARTITEMS_NUM 4
   1253  1.40  dholland #define OPTIONSITEMS_NUM 5
   1254  1.40  dholland 
   1255  1.40  dholland static int mainpos;
   1256  1.40  dholland static bool connected;
   1257  1.40  dholland 
   1258  1.40  dholland static bool joinactive;
   1259  1.40  dholland static int joinpos;
   1260  1.40  dholland static int joinscroll;
   1261  1.40  dholland static int joinable[NSCENE];
   1262  1.40  dholland static int numjoinable;
   1263  1.40  dholland 
   1264  1.40  dholland static bool startactive;
   1265  1.40  dholland static int startpos;
   1266  1.40  dholland static int startscenario;
   1267  1.40  dholland 
   1268  1.40  dholland static bool optionsactive;
   1269  1.40  dholland static int optionspos;
   1270  1.40  dholland static char o_myname[MAXNAMESIZE];
   1271  1.40  dholland static bool o_randomize;
   1272  1.40  dholland static bool o_longfmt;
   1273  1.40  dholland static bool o_nobells;
   1274  1.40  dholland 
   1275  1.40  dholland 
   1276  1.40  dholland /*
   1277  1.40  dholland  * this and sgetstr() should share code
   1278  1.40  dholland  */
   1279  1.40  dholland static void
   1280  1.40  dholland startup_getstr(int y, int x, char *buf, size_t max)
   1281  1.40  dholland {
   1282  1.40  dholland 	size_t pos = 0;
   1283  1.40  dholland 	int ch;
   1284  1.40  dholland 
   1285  1.40  dholland 	for (;;) {
   1286  1.40  dholland 		buf[pos] = 0;
   1287  1.40  dholland 		move(y, x);
   1288  1.40  dholland 		addstr(buf);
   1289  1.40  dholland 		clrtoeol();
   1290  1.40  dholland 		wrefresh(stdscr);
   1291  1.40  dholland 		fflush(stdout);
   1292  1.40  dholland 
   1293  1.40  dholland 		ch = getch();
   1294  1.40  dholland 		switch (ch) {
   1295  1.40  dholland 		case '\n':
   1296  1.40  dholland 		case '\r':
   1297  1.40  dholland 			return;
   1298  1.40  dholland 		case '\b':
   1299  1.40  dholland 			if (pos > 0) {
   1300  1.40  dholland 				/*waddstr(scroll_w, "\b \b");*/
   1301  1.40  dholland 				pos--;
   1302  1.40  dholland 			}
   1303  1.40  dholland 			break;
   1304  1.40  dholland 		default:
   1305  1.40  dholland 			if (ch >= ' ' && ch < 0x7f && pos < max - 1) {
   1306  1.40  dholland 				buf[pos++] = ch;
   1307  1.40  dholland 			} else {
   1308  1.40  dholland 				beep();
   1309  1.40  dholland 			}
   1310  1.40  dholland 		}
   1311  1.40  dholland 	}
   1312  1.40  dholland }
   1313  1.40  dholland 
   1314  1.40  dholland static void
   1315  1.40  dholland changename(void)
   1316  1.40  dholland {
   1317  1.40  dholland 	mvaddstr(LINES-2, COLS/2, "Enter your name:");
   1318  1.40  dholland 	startup_getstr(LINES-1, COLS/2, o_myname, sizeof(o_myname));
   1319  1.40  dholland }
   1320  1.40  dholland 
   1321  1.40  dholland static void
   1322  1.40  dholland checkforgames(void)
   1323  1.40  dholland {
   1324  1.40  dholland 	int i;
   1325  1.40  dholland 	int prev;
   1326  1.40  dholland 
   1327  1.40  dholland 	if (numjoinable > 0) {
   1328  1.40  dholland 		prev = joinable[joinpos];
   1329  1.40  dholland 	} else {
   1330  1.40  dholland 		prev = 0;
   1331  1.40  dholland 	}
   1332  1.40  dholland 
   1333  1.40  dholland 	numjoinable = 0;
   1334  1.40  dholland 	for (i = 0; i < NSCENE; i++) {
   1335  1.40  dholland 		if (!sync_exists(i)) {
   1336  1.40  dholland 			continue;
   1337  1.40  dholland 		}
   1338  1.40  dholland 		if (i < prev) {
   1339  1.40  dholland 			joinpos = numjoinable;
   1340  1.40  dholland 		}
   1341  1.40  dholland 		joinable[numjoinable++] = i;
   1342  1.40  dholland 	}
   1343  1.40  dholland 	if (joinpos > numjoinable) {
   1344  1.40  dholland 		joinpos = (numjoinable > 0) ? numjoinable - 1 : 0;
   1345  1.40  dholland 	}
   1346  1.40  dholland 	if (joinscroll > joinpos) {
   1347  1.40  dholland 		joinscroll = (joinpos > 0) ? joinpos - 1 : 0;
   1348  1.40  dholland 	}
   1349  1.40  dholland }
   1350  1.40  dholland 
   1351  1.40  dholland static void
   1352  1.40  dholland drawstartmenus(void)
   1353  1.40  dholland {
   1354  1.40  dholland 	const int mainy0 = 8;
   1355  1.40  dholland 	const int mainx0 = 12;
   1356  1.40  dholland 
   1357  1.40  dholland 	erase();
   1358  1.40  dholland 
   1359  1.40  dholland 	mvaddstr(5, 10, "Wooden Ships & Iron Men");
   1360  1.40  dholland 
   1361  1.40  dholland 	mvaddselstr(mainy0+0, mainx0, 0, mainpos, 17, "Join a game");
   1362  1.40  dholland 	mvaddselstr(mainy0+1, mainx0, 1, mainpos, 17, "Start a game");
   1363  1.40  dholland 	mvaddselstr(mainy0+2, mainx0, 2, mainpos, 17, "Options");
   1364  1.40  dholland 	mvaddselstr(mainy0+3, mainx0, 3, mainpos, 17, "Show high scores");
   1365  1.40  dholland 	mvaddselstr(mainy0+4, mainx0, 4, mainpos, 17, "Quit");
   1366  1.40  dholland 
   1367  1.40  dholland 	mvprintw(15, 10, "Captain %s", myname);
   1368  1.40  dholland 	if (connected) {
   1369  1.40  dholland 		mvaddstr(16, 10, "Connected via scratch files.");
   1370  1.40  dholland 	} else {
   1371  1.40  dholland 		mvaddstr(16, 10, "Not connected.");
   1372  1.40  dholland 	}
   1373  1.40  dholland 
   1374  1.40  dholland 	if (joinactive) {
   1375  1.40  dholland 		int y0, leavey = 0, i, sc;
   1376  1.40  dholland 
   1377  1.40  dholland 		mvaddstr(0, COLS/2, "## SHIPS  TITLE");
   1378  1.40  dholland 		y0 = 1;
   1379  1.40  dholland 		for (i = 0; i < numjoinable; i++) {
   1380  1.40  dholland 			if (i >= joinscroll && i < joinscroll + LINES-1) {
   1381  1.40  dholland 				move(y0 + i - joinscroll, COLS/2);
   1382  1.40  dholland 				if (i == joinpos) {
   1383  1.40  dholland 					attron(A_REVERSE);
   1384  1.40  dholland 				}
   1385  1.40  dholland 				sc = joinable[i];
   1386  1.40  dholland 				printw("%-2d %-5d  %s",
   1387  1.40  dholland 				       sc, scene[sc].vessels, scene[sc].name);
   1388  1.40  dholland 				if (i == joinpos) {
   1389  1.40  dholland 					filltoeol();
   1390  1.40  dholland 					attroff(A_REVERSE);
   1391  1.40  dholland 					leavey = y0 + i - joinscroll;
   1392  1.40  dholland 				}
   1393  1.40  dholland 			}
   1394  1.40  dholland 		}
   1395  1.40  dholland 		mvaddstr(19, 10, "(Esc to abort)");
   1396  1.40  dholland 		if (numjoinable > 0) {
   1397  1.40  dholland 			mvaddstr(18, 10, "Choose a game to join.");
   1398  1.40  dholland 			move(leavey, COLS-1);
   1399  1.40  dholland 		} else {
   1400  1.40  dholland 			mvaddstr(2, COLS/2, "No games.");
   1401  1.40  dholland 			mvaddstr(18, 10, "Press return to refresh.");
   1402  1.40  dholland 		}
   1403  1.40  dholland 
   1404  1.40  dholland 	} else if (startactive) {
   1405  1.40  dholland 		const char *name;
   1406  1.40  dholland 
   1407  1.40  dholland 		mvaddstr(18, 10, "Start a new game");
   1408  1.40  dholland 		mvaddstr(19, 10, "(Esc to abort)");
   1409  1.40  dholland 		mvaddstr(2, COLS/2, "New game");
   1410  1.40  dholland 
   1411  1.40  dholland 		name = (startscenario < 0) ?
   1412  1.40  dholland 			"not selected" : scene[startscenario].name;
   1413  1.40  dholland 
   1414  1.40  dholland 		mvselprintw(4, COLS/2, 0, startpos, COLS/2 - 1,
   1415  1.40  dholland 			    "Scenario: %s", name);
   1416  1.40  dholland 		mvaddselstr(5, COLS/2, 1, startpos, COLS/2 - 1,
   1417  1.40  dholland 			    "Visibility: local");
   1418  1.40  dholland 		mvaddselstr(6, COLS/2, 2, startpos, COLS/2 - 1,
   1419  1.40  dholland 			    "Password: unset");
   1420  1.40  dholland 		mvaddselstr(7, COLS/2, 3, startpos, COLS/2 - 1,
   1421  1.40  dholland 			    "Start game");
   1422  1.40  dholland 		move(4+startpos, COLS - 2);
   1423  1.40  dholland 
   1424  1.40  dholland 	} else if (optionsactive) {
   1425  1.40  dholland 		mvaddstr(18, 10, "Adjust options");
   1426  1.40  dholland 		mvaddstr(19, 10, "(Esc to abort)");
   1427  1.40  dholland 		mvaddstr(2, COLS/2, "Adjust options");
   1428  1.40  dholland 
   1429  1.40  dholland 		mvselprintw(4, COLS/2, 0, optionspos, COLS/2-1,
   1430  1.40  dholland 			    "Your name: %s", o_myname);
   1431  1.40  dholland 		mvselprintw(5, COLS/2, 1, optionspos, COLS/2-1,
   1432  1.40  dholland 			    "Auto-pick ships: %s", o_randomize ? "ON" : "off");
   1433  1.40  dholland 		mvselprintw(6, COLS/2, 2, optionspos, COLS/2-1,
   1434  1.40  dholland 			    "Usernames in scores: %s",
   1435  1.40  dholland 			    o_longfmt ? "ON" : "off");
   1436  1.40  dholland 		mvselprintw(7, COLS/2, 3, optionspos, COLS/2-1,
   1437  1.40  dholland 			    "Beeping: %s", o_nobells ? "OFF" : "on");
   1438  1.40  dholland 		mvselprintw(8, COLS/2, 4, optionspos, COLS/2-1,
   1439  1.40  dholland 			    "Apply changes");
   1440  1.40  dholland 		move(4+optionspos, COLS - 2);
   1441  1.40  dholland 
   1442  1.40  dholland 	} else {
   1443  1.40  dholland 		move(mainy0 + mainpos, mainx0 + 16);
   1444  1.40  dholland 	}
   1445  1.40  dholland 
   1446  1.40  dholland 	wrefresh(stdscr);
   1447  1.40  dholland 	fflush(stdout);
   1448  1.40  dholland }
   1449  1.40  dholland 
   1450  1.40  dholland void
   1451  1.40  dholland startup(void)
   1452  1.40  dholland {
   1453  1.40  dholland 	int ch;
   1454  1.40  dholland 
   1455  1.40  dholland 	connected = false;
   1456  1.40  dholland 	mainpos = 0;
   1457  1.40  dholland 
   1458  1.40  dholland 	joinactive = false;
   1459  1.40  dholland 	joinpos = 0;
   1460  1.40  dholland 	joinscroll = 0;
   1461  1.40  dholland 	numjoinable = 0;
   1462  1.40  dholland 
   1463  1.40  dholland 	startactive = false;
   1464  1.40  dholland 	startpos = 0;
   1465  1.40  dholland 	startscenario = -1;
   1466  1.40  dholland 
   1467  1.40  dholland 	optionsactive = false;
   1468  1.40  dholland 	optionspos = 0;
   1469  1.40  dholland 
   1470  1.40  dholland 	while (1) {
   1471  1.40  dholland 		if (joinactive) {
   1472  1.40  dholland 			checkforgames();
   1473  1.40  dholland 		}
   1474  1.40  dholland 		drawstartmenus();
   1475  1.40  dholland 		ch = getch();
   1476  1.40  dholland 		switch (ch) {
   1477  1.40  dholland 		    case 12 /*^L*/:
   1478  1.40  dholland 			clear();
   1479  1.40  dholland 			break;
   1480  1.40  dholland 		    case '\r':
   1481  1.40  dholland 		    case '\n':
   1482  1.40  dholland 			if (joinactive && numjoinable > 0) {
   1483  1.40  dholland 				game = joinable[joinpos];
   1484  1.40  dholland 				startgame();
   1485  1.40  dholland 				joinactive = false;
   1486  1.40  dholland 			} else if (startactive) {
   1487  1.40  dholland 				switch (startpos) {
   1488  1.40  dholland 				    case 0:
   1489  1.40  dholland 					startscenario = pickscenario(startscenario);
   1490  1.40  dholland 					startpos = 3;
   1491  1.40  dholland 					break;
   1492  1.40  dholland 				    case 1:
   1493  1.40  dholland 				    case 2:
   1494  1.40  dholland 					oops(21, 10, "That doesn't work yet.");
   1495  1.40  dholland 					break;
   1496  1.40  dholland 				    case 3:
   1497  1.40  dholland 					if (startscenario >= 0) {
   1498  1.40  dholland 						game = startscenario;
   1499  1.40  dholland 						/* can't do this here yet */
   1500  1.40  dholland 						/*startdriver();*/
   1501  1.40  dholland 						startgame();
   1502  1.40  dholland 						startactive = false;
   1503  1.40  dholland 						startscenario = -1;
   1504  1.40  dholland 					} else {
   1505  1.40  dholland 						oops(21, 10,
   1506  1.40  dholland 						     "Pick a scenario.");
   1507  1.40  dholland 					}
   1508  1.40  dholland 					break;
   1509  1.40  dholland 				}
   1510  1.40  dholland 			} else if (optionsactive) {
   1511  1.40  dholland 				switch (optionspos) {
   1512  1.40  dholland 				    case 0: changename(); break;
   1513  1.40  dholland 				    case 1: o_randomize = !o_randomize; break;
   1514  1.40  dholland 				    case 2: o_longfmt = !o_longfmt; break;
   1515  1.40  dholland 				    case 3: o_nobells = !o_nobells; break;
   1516  1.40  dholland 				    case 4:
   1517  1.40  dholland 					strlcpy(myname, o_myname,
   1518  1.40  dholland 						sizeof(myname));
   1519  1.40  dholland 					randomize = o_randomize;
   1520  1.40  dholland 					longfmt = o_longfmt;
   1521  1.40  dholland 					nobells = o_nobells;
   1522  1.40  dholland 					optionsactive = false;
   1523  1.40  dholland 					break;
   1524  1.40  dholland 				}
   1525  1.40  dholland 			} else {
   1526  1.40  dholland 				switch (mainpos) {
   1527  1.40  dholland 				    case 0: joinactive = true; break;
   1528  1.40  dholland 				    case 1: startactive = true; break;
   1529  1.40  dholland 				    case 2:
   1530  1.40  dholland 					strlcpy(o_myname, myname,
   1531  1.40  dholland 						sizeof(o_myname));
   1532  1.40  dholland 					o_randomize = randomize;
   1533  1.40  dholland 					o_longfmt = longfmt;
   1534  1.40  dholland 					o_nobells = nobells;
   1535  1.40  dholland 					optionsactive = true;
   1536  1.40  dholland 					break;
   1537  1.40  dholland 				    case 3: lo_curses(); break;
   1538  1.40  dholland 				    case 4: return;
   1539  1.40  dholland 				}
   1540  1.40  dholland 			}
   1541  1.40  dholland 			break;
   1542  1.40  dholland 		    case 7 /*^G*/:
   1543  1.40  dholland 		    case 8 /*^H*/:
   1544  1.40  dholland 		    case 27 /*ESC*/:
   1545  1.40  dholland 		    case 127 /*^?*/:
   1546  1.40  dholland 			if (joinactive) {
   1547  1.40  dholland 				joinactive = false;
   1548  1.40  dholland 			} else if (startactive) {
   1549  1.40  dholland 				startactive = false;
   1550  1.40  dholland 			} else if (optionsactive) {
   1551  1.40  dholland 				optionsactive = false;
   1552  1.40  dholland 			} else {
   1553  1.40  dholland 				/* nothing */
   1554  1.40  dholland 			}
   1555  1.40  dholland 			break;
   1556  1.40  dholland 		    case 16 /*^P*/:
   1557  1.40  dholland 		    case KEY_UP:
   1558  1.40  dholland 			if (joinactive) {
   1559  1.40  dholland 				up(&joinpos, &joinscroll);
   1560  1.40  dholland 			} else if (startactive) {
   1561  1.40  dholland 				up(&startpos, NULL);
   1562  1.40  dholland 			} else if (optionsactive) {
   1563  1.40  dholland 				up(&optionspos, NULL);
   1564  1.40  dholland 			} else {
   1565  1.40  dholland 				up(&mainpos, NULL);
   1566  1.40  dholland 			}
   1567  1.40  dholland 			break;
   1568  1.40  dholland 		    case 14 /*^N*/:
   1569  1.40  dholland 		    case KEY_DOWN:
   1570  1.40  dholland 			if (joinactive) {
   1571  1.40  dholland 				down(&joinpos, &joinscroll,
   1572  1.40  dholland 				     numjoinable, LINES-1);
   1573  1.40  dholland 			} else if (startactive) {
   1574  1.40  dholland 				down(&startpos, NULL,
   1575  1.40  dholland 				     STARTITEMS_NUM, STARTITEMS_NUM);
   1576  1.40  dholland 			} else if (optionsactive) {
   1577  1.40  dholland 				down(&optionspos, NULL,
   1578  1.40  dholland 				     OPTIONSITEMS_NUM, OPTIONSITEMS_NUM);
   1579  1.40  dholland 			} else {
   1580  1.40  dholland 				down(&mainpos, NULL,
   1581  1.40  dholland 				     MAINITEMS_NUM, MAINITEMS_NUM);
   1582  1.40  dholland 			}
   1583  1.40  dholland 			break;
   1584  1.40  dholland 		    default:
   1585  1.40  dholland 			beep();
   1586  1.40  dholland 			break;
   1587  1.40  dholland 		}
   1588  1.40  dholland 	}
   1589  1.40  dholland }
   1590