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