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