Home | History | Annotate | Line # | Download | only in sail
pl_7.c revision 1.37
      1 /*	$NetBSD: pl_7.c,v 1.37 2009/03/15 22:19:23 dholland 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.37 2009/03/15 22:19:23 dholland Exp $");
     38 #endif
     39 #endif /* not lint */
     40 
     41 #include <curses.h>
     42 #include <err.h>
     43 #include <errno.h>
     44 #include <signal.h>
     45 #include <stdarg.h>
     46 #include <stdio.h>
     47 #include <stdlib.h>
     48 #include <string.h>
     49 #include "array.h"
     50 #include "extern.h"
     51 #include "player.h"
     52 #include "display.h"
     53 
     54 /*
     55  * Use values above KEY_MAX for custom keycodes. (blymn@ says this is ok)
     56  */
     57 #define KEY_ESC(ch) (KEY_MAX+10+ch)
     58 
     59 
     60 /*
     61  * Display interface
     62  */
     63 
     64 static void draw_view(void);
     65 static void draw_turn(void);
     66 static void draw_stat(void);
     67 static void draw_slot(void);
     68 static void draw_board(void);
     69 
     70 static struct stringarray *sc_lines;
     71 static unsigned sc_scrollup;
     72 static bool sc_hasprompt;
     73 static bool sc_hideprompt;
     74 static const char *sc_prompt;
     75 static const char *sc_buf;
     76 
     77 static WINDOW *view_w;
     78 static WINDOW *turn_w;
     79 static WINDOW *stat_w;
     80 static WINDOW *slot_w;
     81 static WINDOW *scroll_w;
     82 
     83 static bool obp[3];
     84 static bool dbp[3];
     85 
     86 int done_curses;
     87 int loaded, fired, changed, repaired;
     88 int dont_adjust;
     89 int viewrow, viewcol;
     90 char movebuf[sizeof SHIP(0)->file->movebuf];
     91 int player;
     92 struct ship *ms;		/* memorial structure, &cc->ship[player] */
     93 struct File *mf;		/* ms->file */
     94 struct shipspecs *mc;		/* ms->specs */
     95 
     96 ////////////////////////////////////////////////////////////
     97 // overall initialization
     98 
     99 static
    100 void
    101 define_esc_key(int ch)
    102 {
    103 	char seq[3] = { '\x1b', ch, 0 };
    104 
    105 	define_key(seq, KEY_ESC(ch));
    106 }
    107 
    108 void
    109 initscreen(void)
    110 {
    111 	int ch;
    112 
    113 	sc_lines = stringarray_create();
    114 	if (sc_lines == NULL) {
    115 		err(1, "malloc");
    116 	}
    117 
    118 	if (signal(SIGTSTP, SIG_DFL) == SIG_ERR) {
    119 		err(1, "signal(SIGTSTP)");
    120 	}
    121 
    122 	if (initscr() == NULL) {
    123 		errx(1, "Can't sail on this terminal.");
    124 	}
    125 	if (STAT_R >= COLS || SCROLL_Y <= 0) {
    126 		errx(1, "Window/terminal not large enough.");
    127 	}
    128 
    129 	view_w = newwin(VIEW_Y, VIEW_X, VIEW_T, VIEW_L);
    130 	slot_w = newwin(SLOT_Y, SLOT_X, SLOT_T, SLOT_L);
    131 	scroll_w = newwin(SCROLL_Y, SCROLL_X, SCROLL_T, SCROLL_L);
    132 	stat_w = newwin(STAT_Y, STAT_X, STAT_T, STAT_L);
    133 	turn_w = newwin(TURN_Y, TURN_X, TURN_T, TURN_L);
    134 
    135 	if (view_w == NULL ||
    136 	    slot_w == NULL ||
    137 	    scroll_w == NULL ||
    138 	    stat_w == NULL ||
    139 	    turn_w == NULL) {
    140 		endwin();
    141 		errx(1, "Curses initialization failed.");
    142 	}
    143 
    144 	leaveok(view_w, 1);
    145 	leaveok(slot_w, 1);
    146 	leaveok(stat_w, 1);
    147 	leaveok(turn_w, 1);
    148 	noecho();
    149 	cbreak();
    150 
    151 	/*
    152 	 * Define esc-x keys
    153 	 */
    154 	for (ch = 0; ch < 127; ch++) {
    155 		define_esc_key(ch);
    156 	}
    157 
    158 	done_curses++;
    159 }
    160 
    161 void
    162 cleanupscreen(void)
    163 {
    164 	/* alarm already turned off */
    165 	if (done_curses) {
    166 		wmove(scroll_w, SCROLL_Y - 1, 0);
    167 		wclrtoeol(scroll_w);
    168 		display_redraw();
    169 		endwin();
    170 	}
    171 }
    172 
    173 ////////////////////////////////////////////////////////////
    174 // scrolling message area
    175 
    176 static void
    177 scrollarea_add(const char *text)
    178 {
    179 	char *copy;
    180 	int errsave;
    181 
    182 	copy = strdup(text);
    183 	if (copy == NULL) {
    184 		goto nomem;
    185 	}
    186 	if (stringarray_add(sc_lines, copy, NULL)) {
    187 		goto nomem;
    188 	}
    189 	return;
    190 
    191 nomem:
    192 	/*
    193 	 * XXX this should use leave(), but that won't
    194 	 * currently work right.
    195 	 */
    196 	errsave = errno;
    197 #if 0
    198 	leave(LEAVE_MALLOC);
    199 #else
    200 	cleanupscreen();
    201 	sync_close(!hasdriver);
    202 	errno = errsave;
    203 	err(1, "malloc");
    204 #endif
    205 }
    206 
    207 static void
    208 draw_scroll(void)
    209 {
    210 	unsigned total_lines;
    211 	unsigned visible_lines;
    212 	unsigned index_of_top;
    213 	unsigned index_of_y;
    214 	unsigned y;
    215 	unsigned cursorx;
    216 
    217 	werase(scroll_w);
    218 
    219 	/* XXX: SCROLL_Y and whatnot should be unsigned too */
    220 	visible_lines = SCROLL_Y - 1;
    221 
    222 	total_lines = stringarray_num(sc_lines);
    223 	if (total_lines > visible_lines) {
    224 		index_of_top = total_lines - visible_lines;
    225 	} else {
    226 		index_of_top = 0;
    227 	}
    228 	if (index_of_top < sc_scrollup) {
    229 		index_of_top = 0;
    230 	} else {
    231 		index_of_top -= sc_scrollup;
    232 	}
    233 
    234 	for (y = 0; y < visible_lines; y++) {
    235 		index_of_y = index_of_top + y;
    236 		if (index_of_y >= total_lines) {
    237 			break;
    238 		}
    239 		wmove(scroll_w, y, 0);
    240 		waddstr(scroll_w, stringarray_get(sc_lines, index_of_y));
    241 	}
    242 	if (sc_hasprompt && !sc_hideprompt) {
    243 		wmove(scroll_w, SCROLL_Y-1, 0);
    244 		waddstr(scroll_w, sc_prompt);
    245 		waddstr(scroll_w, sc_buf);
    246 		cursorx = strlen(sc_prompt) + strlen(sc_buf);
    247 		wmove(scroll_w, SCROLL_Y-1, cursorx);
    248 	}
    249 	else {
    250 		wmove(scroll_w, SCROLL_Y-1, 0);
    251 	}
    252 }
    253 
    254 /*VARARGS2*/
    255 void
    256 Signal(const char *fmt, struct ship *ship, ...)
    257 {
    258 	va_list ap;
    259 	char format[BUFSIZ];
    260 	char buf[BUFSIZ];
    261 
    262 	if (!done_curses)
    263 		return;
    264 	va_start(ap, ship);
    265 	if (*fmt == '\a') {
    266 		beep();
    267 		fmt++;
    268 	}
    269 	fmtship(format, sizeof(format), fmt, ship);
    270 	vsnprintf(buf, sizeof(buf), format, ap);
    271 	va_end(ap);
    272 	scrollarea_add(buf);
    273 }
    274 
    275 /*VARARGS2*/
    276 void
    277 Msg(const char *fmt, ...)
    278 {
    279 	va_list ap;
    280 	char buf[BUFSIZ];
    281 
    282 	if (!done_curses)
    283 		return;
    284 	va_start(ap, fmt);
    285 	if (*fmt == '\a') {
    286 		beep();
    287 		fmt++;
    288 	}
    289 	vsnprintf(buf, sizeof(buf), fmt, ap);
    290 	va_end(ap);
    291 	scrollarea_add(buf);
    292 }
    293 
    294 void
    295 prompt(const char *p, struct ship *ship)
    296 {
    297 	static char buf[BUFSIZ];
    298 
    299 	fmtship(buf, sizeof(buf), p, ship);
    300 	sc_prompt = buf;
    301 	sc_buf = "";
    302 	sc_hasprompt = true;
    303 }
    304 
    305 static void
    306 endprompt(void)
    307 {
    308 	sc_prompt = NULL;
    309 	sc_buf = NULL;
    310 	sc_hasprompt = false;
    311 }
    312 
    313 /*
    314  * Next two functions called from newturn() to poke display. Shouldn't
    315  * exist... XXX
    316  */
    317 
    318 void
    319 display_hide_prompt(void)
    320 {
    321 	sc_hideprompt = true;
    322 	draw_scroll();
    323 	wrefresh(scroll_w);
    324 }
    325 
    326 void
    327 display_reshow_prompt(void)
    328 {
    329 	sc_hideprompt = false;
    330 	draw_scroll();
    331 	wrefresh(scroll_w);
    332 }
    333 
    334 
    335 int
    336 sgetch(const char *p, struct ship *ship, int flag)
    337 {
    338 	int c;
    339 	char input[2];
    340 
    341 	prompt(p, ship);
    342 	input[0] = '\0';
    343 	input[1] = '\0';
    344 	sc_buf = input;
    345 	blockalarm();
    346 	draw_scroll();
    347 	wrefresh(scroll_w);
    348 	fflush(stdout);
    349 	unblockalarm();
    350 	while ((c = wgetch(scroll_w)) == EOF)
    351 		;
    352 	if (flag && c >= ' ' && c < 0x7f) {
    353 		blockalarm();
    354 		input[0] = c;
    355 		draw_scroll();
    356 		wrefresh(scroll_w);
    357 		fflush(stdout);
    358 		unblockalarm();
    359 	}
    360 	endprompt();
    361 	return c;
    362 }
    363 
    364 void
    365 sgetstr(const char *pr, char *buf, int n)
    366 {
    367 	int c;
    368 	char *p = buf;
    369 
    370 	prompt(pr, (struct ship *)0);
    371 	sc_buf = buf;
    372 	for (;;) {
    373 		*p = 0;
    374 		blockalarm();
    375 		draw_scroll();
    376 		wrefresh(scroll_w);
    377 		fflush(stdout);
    378 		unblockalarm();
    379 		while ((c = wgetch(scroll_w)) == EOF)
    380 			;
    381 		switch (c) {
    382 		case '\n':
    383 		case '\r':
    384 			endprompt();
    385 			return;
    386 		case '\b':
    387 			if (p > buf) {
    388 				/*waddstr(scroll_w, "\b \b");*/
    389 				p--;
    390 			}
    391 			break;
    392 		default:
    393 			if (c >= ' ' && c < 0x7f && p < buf + n - 1) {
    394 				*p++ = c;
    395 				/*waddch(scroll_w, c);*/
    396 			} else
    397 				beep();
    398 		}
    399 	}
    400 }
    401 
    402 ////////////////////////////////////////////////////////////
    403 // drawing of other panes
    404 
    405 void
    406 display_force_full_redraw(void)
    407 {
    408 	clear();
    409 }
    410 
    411 void
    412 display_redraw(void)
    413 {
    414 	draw_board();
    415 	draw_view();
    416 	draw_turn();
    417 	draw_stat();
    418 	draw_slot();
    419 	draw_scroll();
    420 	/* move the cursor */
    421 	wrefresh(scroll_w);
    422 	/* paranoia */
    423 	fflush(stdout);
    424 }
    425 
    426 static void
    427 draw_view(void)
    428 {
    429 	struct ship *sp;
    430 
    431 	werase(view_w);
    432 	foreachship(sp) {
    433 		if (sp->file->dir
    434 		    && sp->file->row > viewrow
    435 		    && sp->file->row < viewrow + VIEW_Y
    436 		    && sp->file->col > viewcol
    437 		    && sp->file->col < viewcol + VIEW_X) {
    438 			wmove(view_w, sp->file->row - viewrow,
    439 				sp->file->col - viewcol);
    440 			waddch(view_w, colours(sp));
    441 			wmove(view_w,
    442 				sternrow(sp) - viewrow,
    443 				sterncol(sp) - viewcol);
    444 			waddch(view_w, sterncolour(sp));
    445 		}
    446 	}
    447 	wrefresh(view_w);
    448 }
    449 
    450 static void
    451 draw_turn(void)
    452 {
    453 	wmove(turn_w, 0, 0);
    454 	wprintw(turn_w, "%cTurn %d", dont_adjust?'*':'-', turn);
    455 	wrefresh(turn_w);
    456 }
    457 
    458 static void
    459 draw_stat(void)
    460 {
    461 	wmove(stat_w, STAT_1, 0);
    462 	wprintw(stat_w, "Points  %3d\n", mf->points);
    463 	wprintw(stat_w, "Fouls    %2d\n", fouled(ms));
    464 	wprintw(stat_w, "Grapples %2d\n", grappled(ms));
    465 
    466 	wmove(stat_w, STAT_2, 0);
    467 	wprintw(stat_w, "    0 %c(%c)\n",
    468 		maxmove(ms, winddir + 3, -1) + '0',
    469 		maxmove(ms, winddir + 3, 1) + '0');
    470 	waddstr(stat_w, "   \\|/\n");
    471 	wprintw(stat_w, "   -^-%c(%c)\n",
    472 		maxmove(ms, winddir + 2, -1) + '0',
    473 		maxmove(ms, winddir + 2, 1) + '0');
    474 	waddstr(stat_w, "   /|\\\n");
    475 	wprintw(stat_w, "    | %c(%c)\n",
    476 		maxmove(ms, winddir + 1, -1) + '0',
    477 		maxmove(ms, winddir + 1, 1) + '0');
    478 	wprintw(stat_w, "   %c(%c)\n",
    479 		maxmove(ms, winddir, -1) + '0',
    480 		maxmove(ms, winddir, 1) + '0');
    481 
    482 	wmove(stat_w, STAT_3, 0);
    483 	wprintw(stat_w, "Load  %c%c %c%c\n",
    484 		loadname[mf->loadL], readyname(mf->readyL),
    485 		loadname[mf->loadR], readyname(mf->readyR));
    486 	wprintw(stat_w, "Hull %2d\n", mc->hull);
    487 	wprintw(stat_w, "Crew %2d %2d %2d\n",
    488 		mc->crew1, mc->crew2, mc->crew3);
    489 	wprintw(stat_w, "Guns %2d %2d\n", mc->gunL, mc->gunR);
    490 	wprintw(stat_w, "Carr %2d %2d\n", mc->carL, mc->carR);
    491 	wprintw(stat_w, "Rigg %d %d %d ", mc->rig1, mc->rig2, mc->rig3);
    492 	if (mc->rig4 < 0)
    493 		waddch(stat_w, '-');
    494 	else
    495 		wprintw(stat_w, "%d", mc->rig4);
    496 	wrefresh(stat_w);
    497 }
    498 
    499 void
    500 draw_slot(void)
    501 {
    502 	int i;
    503 
    504 	if (!boarding(ms, 0)) {
    505 		mvwaddstr(slot_w, 0, 0, "   ");
    506 		mvwaddstr(slot_w, 1, 0, "   ");
    507 	} else {
    508 		wmove(slot_w, 0, 0);
    509 		for (i = 0; i < 3; i++) {
    510 			waddch(slot_w, obp[i] ? '1'+i : ' ');
    511 		}
    512 		mvwaddstr(slot_w, 1, 0, "OBP");
    513 	}
    514 	if (!boarding(ms, 1)) {
    515 		mvwaddstr(slot_w, 2, 0, "   ");
    516 		mvwaddstr(slot_w, 3, 0, "   ");
    517 	} else {
    518 		wmove(slot_w, 2, 0);
    519 		for (i = 0; i < 3; i++) {
    520 			waddch(slot_w, dbp[i] ? '1'+i : ' ');
    521 		}
    522 		mvwaddstr(slot_w, 3, 0, "DBP");
    523 	}
    524 
    525 	wmove(slot_w, SLOT_Y-4, 0);
    526 	if (mf->RH)
    527 		wprintw(slot_w, "%dRH", mf->RH);
    528 	else
    529 		waddstr(slot_w, "   ");
    530 	wmove(slot_w, SLOT_Y-3, 0);
    531 	if (mf->RG)
    532 		wprintw(slot_w, "%dRG", mf->RG);
    533 	else
    534 		waddstr(slot_w, "   ");
    535 	wmove(slot_w, SLOT_Y-2, 0);
    536 	if (mf->RR)
    537 		wprintw(slot_w, "%dRR", mf->RR);
    538 	else
    539 		waddstr(slot_w, "   ");
    540 
    541 #define Y	(SLOT_Y/2)
    542 	wmove(slot_w, 7, 1);
    543 	wprintw(slot_w,"%d", windspeed);
    544 	mvwaddch(slot_w, Y, 0, ' ');
    545 	mvwaddch(slot_w, Y, 2, ' ');
    546 	mvwaddch(slot_w, Y-1, 0, ' ');
    547 	mvwaddch(slot_w, Y-1, 1, ' ');
    548 	mvwaddch(slot_w, Y-1, 2, ' ');
    549 	mvwaddch(slot_w, Y+1, 0, ' ');
    550 	mvwaddch(slot_w, Y+1, 1, ' ');
    551 	mvwaddch(slot_w, Y+1, 2, ' ');
    552 	wmove(slot_w, Y - dr[winddir], 1 - dc[winddir]);
    553 	switch (winddir) {
    554 	case 1:
    555 	case 5:
    556 		waddch(slot_w, '|');
    557 		break;
    558 	case 2:
    559 	case 6:
    560 		waddch(slot_w, '/');
    561 		break;
    562 	case 3:
    563 	case 7:
    564 		waddch(slot_w, '-');
    565 		break;
    566 	case 4:
    567 	case 8:
    568 		waddch(slot_w, '\\');
    569 		break;
    570 	}
    571 	mvwaddch(slot_w, Y + dr[winddir], 1 + dc[winddir], '+');
    572 	wrefresh(slot_w);
    573 }
    574 
    575 void
    576 draw_board(void)
    577 {
    578 	int n;
    579 
    580 	erase();
    581 	werase(view_w);
    582 	werase(slot_w);
    583 	werase(scroll_w);
    584 	werase(stat_w);
    585 	werase(turn_w);
    586 
    587 	move(BOX_T, BOX_L);
    588 	for (n = 0; n < BOX_X; n++)
    589 		addch('-');
    590 	move(BOX_B, BOX_L);
    591 	for (n = 0; n < BOX_X; n++)
    592 		addch('-');
    593 	for (n = BOX_T+1; n < BOX_B; n++) {
    594 		mvaddch(n, BOX_L, '|');
    595 		mvaddch(n, BOX_R, '|');
    596 	}
    597 	mvaddch(BOX_T, BOX_L, '+');
    598 	mvaddch(BOX_T, BOX_R, '+');
    599 	mvaddch(BOX_B, BOX_L, '+');
    600 	mvaddch(BOX_B, BOX_R, '+');
    601 	refresh();
    602 
    603 #if 0
    604 #define WSaIM "Wooden Ships & Iron Men"
    605 	wmove(view_w, 2, (VIEW_X - sizeof WSaIM - 1) / 2);
    606 	waddstr(view_w, WSaIM);
    607 	wmove(view_w, 4, (VIEW_X - strlen(cc->name)) / 2);
    608 	waddstr(view_w, cc->name);
    609 	wrefresh(view_w);
    610 #endif
    611 
    612 	move(LINE_T, LINE_L);
    613 	printw("Class %d %s (%d guns) '%s' (%c%c)",
    614 		mc->class,
    615 		classname[mc->class],
    616 		mc->guns,
    617 		ms->shipname,
    618 		colours(ms),
    619 		sterncolour(ms));
    620 	refresh();
    621 }
    622 
    623 void
    624 display_set_obp(int which, bool show)
    625 {
    626 	obp[which] = show;
    627 }
    628 
    629 void
    630 display_set_dbp(int which, bool show)
    631 {
    632 	dbp[which] = show;
    633 }
    634 
    635 ////////////////////////////////////////////////////////////
    636 // external actions on the display
    637 
    638 void
    639 display_scroll_pageup(void)
    640 {
    641 	unsigned total_lines, visible_lines, limit;
    642 	unsigned pagesize = SCROLL_Y - 2;
    643 
    644 	total_lines = stringarray_num(sc_lines);
    645 	visible_lines = SCROLL_Y - 1;
    646 	limit = total_lines - visible_lines;
    647 
    648 	sc_scrollup += pagesize;
    649 	if (sc_scrollup > limit) {
    650 		sc_scrollup = limit;
    651 	}
    652 }
    653 
    654 void
    655 display_scroll_pagedown(void)
    656 {
    657 	unsigned pagesize = SCROLL_Y - 2;
    658 
    659 	if (sc_scrollup < pagesize) {
    660 		sc_scrollup = 0;
    661 	} else {
    662 		sc_scrollup -= pagesize;
    663 	}
    664 }
    665 
    666 void
    667 centerview(void)
    668 {
    669 	viewrow = mf->row - VIEW_Y / 2;
    670 	viewcol = mf->col - VIEW_X / 2;
    671 }
    672 
    673 void
    674 upview(void)
    675 {
    676 	viewrow -= VIEW_Y / 3;
    677 }
    678 
    679 void
    680 downview(void)
    681 {
    682 	viewrow += VIEW_Y / 3;
    683 }
    684 
    685 void
    686 leftview(void)
    687 {
    688 	viewcol -= VIEW_X / 5;
    689 }
    690 
    691 void
    692 rightview(void)
    693 {
    694 	viewcol += VIEW_X / 5;
    695 }
    696 
    697 /* Called from newturn()... rename? */
    698 void
    699 display_adjust_view(void)
    700 {
    701 	if (dont_adjust)
    702 		return;
    703 	if (mf->row < viewrow + VIEW_Y/4)
    704 		viewrow = mf->row - (VIEW_Y - VIEW_Y/4);
    705 	else if (mf->row > viewrow + (VIEW_Y - VIEW_Y/4))
    706 		viewrow = mf->row - VIEW_Y/4;
    707 	if (mf->col < viewcol + VIEW_X/8)
    708 		viewcol = mf->col - (VIEW_X - VIEW_X/8);
    709 	else if (mf->col > viewcol + (VIEW_X - VIEW_X/8))
    710 		viewcol = mf->col - VIEW_X/8;
    711 }
    712