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