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