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