1 /* $NetBSD: subs.c,v 1.20 2013/09/13 20:46:50 joerg Exp $ */ 2 3 /* 4 * Copyright (c) 1980, 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[] = "@(#)subs.c 8.1 (Berkeley) 5/31/93"; 36 #else 37 __RCSID("$NetBSD: subs.c,v 1.20 2013/09/13 20:46:50 joerg Exp $"); 38 #endif 39 #endif /* not lint */ 40 41 #include "back.h" 42 43 int buffnum; 44 static char outbuff[BUFSIZ]; 45 46 static const char plred[] = "Player is red, computer is white."; 47 static const char plwhite[] = "Player is white, computer is red."; 48 static const char nocomp[] = "(No computer play.)"; 49 50 void 51 errexit(const char *s) 52 { 53 write(2, "\n", 1); 54 perror(s); 55 getout(0); 56 } 57 58 int 59 addbuf(int c) 60 { 61 buffnum++; 62 if (buffnum == BUFSIZ) { 63 if (write(1, outbuff, BUFSIZ) != BUFSIZ) 64 errexit("addbuf (write):"); 65 buffnum = 0; 66 } 67 outbuff[buffnum] = c; 68 return (0); 69 } 70 71 void 72 buflush(void) 73 { 74 if (buffnum < 0) 75 return; 76 buffnum++; 77 if (write(1, outbuff, buffnum) != buffnum) 78 errexit("buflush (write):"); 79 buffnum = -1; 80 } 81 82 int 83 readc(void) 84 { 85 char c; 86 87 if (tflag) { 88 cline(); 89 newpos(); 90 } 91 buflush(); 92 if (read(0, &c, 1) != 1) 93 errexit("readc"); 94 #ifdef WHY_IS_THIS_HARDWIRED_IN_HERE 95 if (c == '\177') 96 getout(0); 97 #endif 98 if (c == '\033' || c == '\015') 99 return ('\n'); 100 if (cflag) 101 return (c); 102 if (c == '\014') 103 return ('R'); 104 if (c >= 'a' && c <= 'z') 105 return (c & 0137); 106 return (c); 107 } 108 109 void 110 writec(int c) 111 { 112 if (tflag) 113 fancyc(c); 114 else 115 addbuf(c); 116 } 117 118 void 119 writel(const char *l) 120 { 121 #ifdef DEBUG 122 const char *s; 123 124 if (trace == NULL) 125 trace = fopen("bgtrace", "w"); 126 127 fprintf(trace, "writel: \""); 128 for (s = l; *s; s++) { 129 if (*s < ' ' || *s == '\177') 130 fprintf(trace, "^%c", (*s) ^ 0100); 131 else 132 putc(*s, trace); 133 } 134 fprintf(trace, "\"\n"); 135 fflush(trace); 136 #endif 137 138 while (*l) 139 writec(*l++); 140 } 141 142 void 143 proll(struct move *mm) 144 { 145 if (mm->d0) 146 mswap(mm); 147 if (cturn == 1) 148 writel("Red's roll: "); 149 else 150 writel("White's roll: "); 151 writec(mm->D0 + '0'); 152 writec('\040'); 153 writec(mm->D1 + '0'); 154 if (tflag) 155 cline(); 156 } 157 158 void 159 wrint(int n) 160 { 161 int i, j, t; 162 163 for (i = 4; i > 0; i--) { 164 t = 1; 165 for (j = 0; j < i; j++) 166 t *= 10; 167 if (n > t - 1) 168 writec((n / t) % 10 + '0'); 169 } 170 writec(n % 10 + '0'); 171 } 172 173 void 174 gwrite(void) 175 { 176 int r, c; 177 178 r = c = 0; 179 if (tflag) { 180 r = curr; 181 c = curc; 182 curmove(16, 0); 183 } 184 if (gvalue > 1) { 185 writel("Game value: "); 186 wrint(gvalue); 187 writel(". "); 188 if (dlast == -1) 189 writel(color[0]); 190 else 191 writel(color[1]); 192 writel(" doubled last."); 193 } else { 194 switch (pnum) { 195 case -1: /* player is red */ 196 writel(plred); 197 break; 198 case 0: /* player is both colors */ 199 writel(nocomp); 200 break; 201 case 1: /* player is white */ 202 writel(plwhite); 203 } 204 } 205 206 if (rscore || wscore) { 207 writel(" "); 208 wrscore(); 209 } 210 if (tflag) { 211 cline(); 212 curmove(r, c); 213 } 214 } 215 216 int 217 quit(struct move *mm) 218 { 219 220 if (tflag) { 221 curmove(20, 0); 222 clend(); 223 } else 224 writec('\n'); 225 writel("Are you sure you want to quit?"); 226 if (yorn(0)) { 227 if (rfl) { 228 writel("Would you like to save this game?"); 229 if (yorn(0)) 230 save(mm, 0); 231 } 232 cturn = 0; 233 return (1); 234 } 235 return (0); 236 } 237 238 int 239 yorn(int special) 240 { 241 char c; 242 int i; 243 244 i = 1; 245 while ((c = readc()) != 'Y' && c != 'N') { 246 if (special && c == special) 247 return (2); 248 if (i) { 249 if (special) { 250 writel(" (Y, N, or "); 251 writec(special); 252 writec(')'); 253 } else 254 writel(" (Y or N)"); 255 i = 0; 256 } else 257 writec('\007'); 258 } 259 if (c == 'Y') 260 writel(" Yes.\n"); 261 else 262 writel(" No.\n"); 263 if (tflag) 264 buflush(); 265 return (c == 'Y'); 266 } 267 268 void 269 wrhit(int i) 270 { 271 writel("Blot hit on "); 272 wrint(i); 273 writec('.'); 274 writec('\n'); 275 } 276 277 void 278 nexturn(void) 279 { 280 int c; 281 282 cturn = -cturn; 283 c = cturn / abs(cturn); 284 home = bar; 285 bar = 25 - bar; 286 offptr += c; 287 offopp -= c; 288 inptr += c; 289 inopp -= c; 290 Colorptr += c; 291 colorptr += c; 292 } 293 294 void 295 getarg(struct move *mm, char ***arg) 296 { 297 char **s; 298 299 /* process arguments here. dashes are ignored, nbrw are ignored if 300 * the game is being recovered */ 301 302 s = *arg; 303 while (*s && s[0][0] == '-') { 304 switch (s[0][1]) { 305 306 /* don't ask if rules or instructions needed */ 307 case 'n': 308 if (rflag) 309 break; 310 aflag = 0; 311 args[acnt++] = 'n'; 312 break; 313 314 /* player is both red and white */ 315 case 'b': 316 if (rflag) 317 break; 318 pnum = 0; 319 aflag = 0; 320 args[acnt++] = 'b'; 321 break; 322 323 /* player is red */ 324 case 'r': 325 if (rflag) 326 break; 327 pnum = -1; 328 aflag = 0; 329 args[acnt++] = 'r'; 330 break; 331 332 /* player is white */ 333 case 'w': 334 if (rflag) 335 break; 336 pnum = 1; 337 aflag = 0; 338 args[acnt++] = 'w'; 339 break; 340 341 /* print board after move according to following 342 * character */ 343 case 'p': 344 if (s[0][2] != 'r' && s[0][2] != 'w' && s[0][2] != 'b') 345 break; 346 args[acnt++] = 'p'; 347 args[acnt++] = s[0][2]; 348 if (s[0][2] == 'r') 349 bflag = 1; 350 if (s[0][2] == 'w') 351 bflag = -1; 352 if (s[0][2] == 'b') 353 bflag = 0; 354 break; 355 356 case 't': 357 if (s[0][2] == '\0') { /* get terminal caps */ 358 s++; 359 tflag = getcaps(*s); 360 } else 361 tflag = getcaps(&s[0][2]); 362 break; 363 364 case 's': 365 s++; 366 /* recover file */ 367 if (s[0] == NULL) { 368 writel("No save file named\n"); 369 getout(0); 370 } else 371 recover(mm, s[0]); 372 break; 373 } 374 s++; 375 } 376 if (s[0] != 0) 377 recover(mm, s[0]); 378 } 379 380 void 381 init(void) 382 { 383 int i; 384 385 for (i = 0; i < 26;) 386 board[i++] = 0; 387 board[1] = 2; 388 board[6] = board[13] = -5; 389 board[8] = -3; 390 board[12] = board[19] = 5; 391 board[17] = 3; 392 board[24] = -2; 393 off[0] = off[1] = -15; 394 in[0] = in[1] = 5; 395 gvalue = 1; 396 dlast = 0; 397 } 398 399 void 400 wrscore(void) 401 { 402 writel("Score: "); 403 writel(color[1]); 404 writec(' '); 405 wrint(rscore); 406 writel(", "); 407 writel(color[0]); 408 writec(' '); 409 wrint(wscore); 410 } 411 412 void 413 fixtty(struct termios *t) 414 { 415 if (tflag) 416 newpos(); 417 buflush(); 418 if (tcsetattr(0, TCSADRAIN, t) < 0) 419 errexit("fixtty"); 420 } 421 422 void 423 getout(int dummy __unused) 424 { 425 /* go to bottom of screen */ 426 if (tflag) { 427 curmove(23, 0); 428 cline(); 429 } else 430 writec('\n'); 431 432 /* fix terminal status */ 433 fixtty(&old); 434 exit(0); 435 } 436 437 void 438 roll(struct move *mm) 439 { 440 char c; 441 int row; 442 int col; 443 444 row = col = 0; 445 if (iroll) { 446 if (tflag) { 447 row = curr; 448 col = curc; 449 curmove(17, 0); 450 } else 451 writec('\n'); 452 writel("ROLL: "); 453 c = readc(); 454 if (c != '\n') { 455 while (c < '1' || c > '6') 456 c = readc(); 457 mm->D0 = c - '0'; 458 writec(' '); 459 writec(c); 460 c = readc(); 461 while (c < '1' || c > '6') 462 c = readc(); 463 mm->D1 = c - '0'; 464 writec(' '); 465 writec(c); 466 if (tflag) { 467 curmove(17, 0); 468 cline(); 469 curmove(row, col); 470 } else 471 writec('\n'); 472 return; 473 } 474 if (tflag) { 475 curmove(17, 0); 476 cline(); 477 curmove(row, col); 478 } else 479 writec('\n'); 480 } 481 mm->D0 = rnum(6) + 1; 482 mm->D1 = rnum(6) + 1; 483 mm->d0 = 0; 484 } 485