bdisp.c revision 1.14
1/* $NetBSD: bdisp.c,v 1.14 2010/03/29 03:51:55 dholland Exp $ */ 2 3/* 4 * Copyright (c) 1994 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Ralph Campbell. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35#include <sys/cdefs.h> 36#ifndef lint 37#if 0 38static char sccsid[] = "@(#)bdisp.c 8.2 (Berkeley) 5/3/95"; 39#else 40__RCSID("$NetBSD: bdisp.c,v 1.14 2010/03/29 03:51:55 dholland Exp $"); 41#endif 42#endif /* not lint */ 43 44#include <curses.h> 45#include <string.h> 46#include <stdlib.h> 47#include <err.h> 48#include "gomoku.h" 49 50#define SCRNH 24 /* assume 24 lines for the moment */ 51#define SCRNW 80 /* assume 80 chars for the moment */ 52 53static int lastline; 54static char pcolor[] = "*O.?"; 55 56extern int interactive; 57extern char *plyr[]; 58 59/* 60 * Initialize screen display. 61 */ 62void 63cursinit(void) 64{ 65 66 if (!initscr()) { 67 errx(EXIT_FAILURE, "Couldn't initialize screen"); 68 } 69 if ((LINES < SCRNH) || (COLS < SCRNW)) { 70 errx(EXIT_FAILURE, "Screen too small (need %d%xd)", 71 SCRNW, SCRNH); 72 } 73 keypad(stdscr, TRUE); 74 nonl(); 75 noecho(); 76 cbreak(); 77 leaveok(stdscr, FALSE); 78 79#if 0 /* no mouse support in netbsd curses yet */ 80 mousemask(BUTTON1_CLICKED, NULL); 81#endif 82} 83 84/* 85 * Restore screen display. 86 */ 87void 88cursfini(void) 89{ 90 91 move(BSZ4, 0); 92 clrtoeol(); 93 refresh(); 94 echo(); 95 endwin(); 96} 97 98/* 99 * Initialize board display. 100 */ 101void 102bdisp_init(void) 103{ 104 int i, j; 105 106 /* top border */ 107 for (i = 1; i < BSZ1; i++) { 108 move(0, 2 * i + 1); 109 addch(letters[i]); 110 } 111 /* left and right edges */ 112 for (j = BSZ1; --j > 0; ) { 113 move(20 - j, 0); 114 printw("%2d ", j); 115 move(20 - j, 2 * BSZ1 + 1); 116 printw("%d ", j); 117 } 118 /* bottom border */ 119 for (i = 1; i < BSZ1; i++) { 120 move(20, 2 * i + 1); 121 addch(letters[i]); 122 } 123 bdwho(0); 124 move(0, 47); 125 addstr("# black white"); 126 lastline = 0; 127 bdisp(); 128} 129 130/* 131 * Update who is playing whom. 132 */ 133void 134bdwho(int update) 135{ 136 int i, j; 137 138 move(21, 0); 139 printw(" "); 140 i = strlen(plyr[BLACK]); 141 j = strlen(plyr[WHITE]); 142 if (i + j <= 20) { 143 move(21, 10 - (i+j)/2); 144 printw("BLACK/%s (*) vs. WHITE/%s (O)", 145 plyr[BLACK], plyr[WHITE]); 146 } else { 147 move(21, 0); 148 if (i <= 10) { 149 j = 20 - i; 150 } else if (j <= 10) { 151 i = 20 - j; 152 } else { 153 i = j = 10; 154 } 155 printw("BLACK/%.*s (*) vs. WHITE/%.*s (O)", 156 i, plyr[BLACK], j, plyr[WHITE]); 157 } 158 if (update) 159 refresh(); 160} 161 162/* 163 * Update the board display after a move. 164 */ 165void 166bdisp(void) 167{ 168 int i, j, c; 169 struct spotstr *sp; 170 171 for (j = BSZ1; --j > 0; ) { 172 for (i = 1; i < BSZ1; i++) { 173 move(BSZ1 - j, 2 * i + 1); 174 sp = &board[i + j * BSZ1]; 175 if (debug > 1 && sp->s_occ == EMPTY) { 176 if (sp->s_flags & IFLAGALL) 177 c = '+'; 178 else if (sp->s_flags & CFLAGALL) 179 c = '-'; 180 else 181 c = '.'; 182 } else 183 c = pcolor[sp->s_occ]; 184 addch(c); 185 } 186 } 187 refresh(); 188} 189 190#ifdef DEBUG 191/* 192 * Dump board display to a file. 193 */ 194void 195bdump(FILE *fp) 196{ 197 int i, j, c; 198 struct spotstr *sp; 199 200 /* top border */ 201 fprintf(fp, " A B C D E F G H J K L M N O P Q R S T\n"); 202 203 for (j = BSZ1; --j > 0; ) { 204 /* left edge */ 205 fprintf(fp, "%2d ", j); 206 for (i = 1; i < BSZ1; i++) { 207 sp = &board[i + j * BSZ1]; 208 if (debug > 1 && sp->s_occ == EMPTY) { 209 if (sp->s_flags & IFLAGALL) 210 c = '+'; 211 else if (sp->s_flags & CFLAGALL) 212 c = '-'; 213 else 214 c = '.'; 215 } else 216 c = pcolor[sp->s_occ]; 217 putc(c, fp); 218 putc(' ', fp); 219 } 220 /* right edge */ 221 fprintf(fp, "%d\n", j); 222 } 223 224 /* bottom border */ 225 fprintf(fp, " A B C D E F G H J K L M N O P Q R S T\n"); 226} 227#endif /* DEBUG */ 228 229/* 230 * Display a transcript entry 231 */ 232void 233dislog(const char *str) 234{ 235 236 if (++lastline >= SCRNH - 1) { 237 /* move 'em up */ 238 lastline = 1; 239 } 240 move(lastline, TRANSCRIPT_COL); 241 addnstr(str, SCRNW - TRANSCRIPT_COL - 1); 242 clrtoeol(); 243 move(lastline + 1, TRANSCRIPT_COL); 244 clrtoeol(); 245} 246 247/* 248 * Display a question. 249 */ 250 251void 252ask(const char *str) 253{ 254 int len = strlen(str); 255 256 move(BSZ4, 0); 257 addstr(str); 258 clrtoeol(); 259 move(BSZ4, len); 260 refresh(); 261} 262 263int 264get_line(char *buf, int size) 265{ 266 char *cp, *end; 267 int c; 268 269 c = 0; 270 cp = buf; 271 end = buf + size - 1; /* save room for the '\0' */ 272 while (cp < end && (c = getchar()) != EOF && c != '\n' && c != '\r') { 273 *cp++ = c; 274 if (interactive) { 275 switch (c) { 276 case 0x0c: /* ^L */ 277 wrefresh(curscr); 278 cp--; 279 continue; 280 case 0x15: /* ^U */ 281 case 0x18: /* ^X */ 282 while (cp > buf) { 283 cp--; 284 addch('\b'); 285 } 286 clrtoeol(); 287 break; 288 case '\b': 289 case 0x7f: /* DEL */ 290 if (cp == buf + 1) { 291 cp--; 292 continue; 293 } 294 cp -= 2; 295 addch('\b'); 296 c = ' '; 297 /* FALLTHROUGH */ 298 default: 299 addch(c); 300 } 301 refresh(); 302 } 303 } 304 *cp = '\0'; 305 return(c != EOF); 306} 307 308/* 309 * Decent (n)curses interface for the game, based on Eric S. Raymond's 310 * modifications to the battleship (bs) user interface. 311 */ 312int 313get_coord(void) 314{ 315 static int curx = BSZ / 2; 316 static int cury = BSZ / 2; 317 int ny, nx, ch; 318 319 BGOTO(cury, curx); 320 refresh(); 321 nx = curx; 322 ny = cury; 323 for (;;) { 324 mvprintw(BSZ3, (BSZ -6)/2, "(%c %d)", 325 'A'+ ((curx > 7) ? (curx+1) : curx), cury + 1); 326 BGOTO(cury, curx); 327 328 ch = getch(); 329 switch (ch) { 330 case 'k': 331 case '8': 332 case KEY_UP: 333 nx = curx; 334 ny = cury + 1; 335 break; 336 case 'j': 337 case '2': 338 case KEY_DOWN: 339 nx = curx; 340 ny = BSZ + cury - 1; 341 break; 342 case 'h': 343 case '4': 344 case KEY_LEFT: 345 nx = BSZ + curx - 1; 346 ny = cury; 347 break; 348 case 'l': 349 case '6': 350 case KEY_RIGHT: 351 nx = curx + 1; 352 ny = cury; 353 break; 354 case 'y': 355 case '7': 356 case KEY_A1: 357 nx = BSZ + curx - 1; 358 ny = cury + 1; 359 break; 360 case 'b': 361 case '1': 362 case KEY_C1: 363 nx = BSZ + curx - 1; 364 ny = BSZ + cury - 1; 365 break; 366 case 'u': 367 case '9': 368 case KEY_A3: 369 nx = curx + 1; 370 ny = cury + 1; 371 break; 372 case 'n': 373 case '3': 374 case KEY_C3: 375 nx = curx + 1; 376 ny = BSZ + cury - 1; 377 break; 378 case 'K': 379 nx = curx; 380 ny = cury + 5; 381 break; 382 case 'J': 383 nx = curx; 384 ny = BSZ + cury - 5; 385 break; 386 case 'H': 387 nx = BSZ + curx - 5; 388 ny = cury; 389 break; 390 case 'L': 391 nx = curx + 5; 392 ny = cury; 393 break; 394 case 'Y': 395 nx = BSZ + curx - 5; 396 ny = cury + 5; 397 break; 398 case 'B': 399 nx = BSZ + curx - 5; 400 ny = BSZ + cury - 5; 401 break; 402 case 'U': 403 nx = curx + 5; 404 ny = cury + 5; 405 break; 406 case 'N': 407 nx = curx + 5; 408 ny = BSZ + cury - 5; 409 break; 410 case '\f': 411 nx = curx; 412 ny = cury; 413 (void)clearok(stdscr, TRUE); 414 (void)refresh(); 415 break; 416#if 0 /* notyet */ 417 case KEY_MOUSE: 418 { 419 MEVENT myevent; 420 421 getmouse(&myevent); 422 if (myevent.y >= 1 && myevent.y <= BSZ1 && 423 myevent.x >= 3 && myevent.x <= (2 * BSZ + 1)) { 424 curx = (myevent.x - 3) / 2; 425 cury = BSZ - myevent.y; 426 return PT(curx,cury); 427 } else { 428 beep(); 429 } 430 } 431 break; 432#endif /* 0 */ 433 case 'Q': 434 return RESIGN; 435 break; 436 case 'S': 437 return SAVE; 438 break; 439 case ' ': 440 case '\r': 441 (void) mvaddstr(BSZ3, (BSZ -6)/2, " "); 442 return PT(curx+1,cury+1); 443 break; 444 } 445 446 curx = nx % BSZ; 447 cury = ny % BSZ; 448 } 449} 450