Initial import from FreeBSD RELENG_4:
[dragonfly.git] / games / sail / pl_main.c
1 /*
2  * Copyright (c) 1983, 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
34 #ifndef lint
35 #if 0
36 static char sccsid[] = "@(#)pl_main.c   8.1 (Berkeley) 5/31/93";
37 #endif
38 static const char rcsid[] =
39  "$FreeBSD: src/games/sail/pl_main.c,v 1.6 1999/11/30 03:49:38 billf Exp $";
40 #endif /* not lint */
41
42 #include "player.h"
43 #include <sys/types.h>
44 #include <sys/wait.h>
45
46 void choke(), child();
47
48 /*ARGSUSED*/
49 pl_main()
50 {
51
52         if (!SCREENTEST()) {
53                 printf("Can't sail on this terminal.\n");
54                 exit(1);
55         }
56         initialize();
57         Signal("Aye aye, Sir", (struct ship *)0);
58         play();
59         return 0;                       /* for lint,  play() never returns */
60 }
61
62 initialize()
63 {
64         register struct File *fp;
65         register struct ship *sp;
66         char captain[80];
67         char message[60];
68         int load;
69         register int n;
70         char *nameptr;
71         int nat[NNATION];
72
73         if (game < 0) {
74                 (void) puts("Choose a scenario:\n");
75                 (void) puts("\n\tNUMBER\tSHIPS\tIN PLAY\tTITLE");
76                 for (n = 0; n < NSCENE; n++) {
77                         /* ( */
78                         printf("\t%d):\t%d\t%s\t%s\n", n, scene[n].vessels,
79                                 sync_exists(n) ? "YES" : "no",
80                                 scene[n].name);
81                 }
82 reprint:
83                 printf("\nScenario number? ");
84                 (void) fflush(stdout);
85                 (void) scanf("%d", &game);
86                 while (getchar() != '\n')
87                         ;
88         }
89         if (game < 0 || game >= NSCENE) {
90                 (void) puts("Very funny.");
91                 exit(1);
92         }
93         cc = &scene[game];
94         ls = SHIP(cc->vessels);
95
96         for (n = 0; n < NNATION; n++)
97                 nat[n] = 0;
98         foreachship(sp) {
99                 if (sp->file == NULL &&
100                     (sp->file = (struct File *)calloc(1, sizeof (struct File))) == NULL) {
101                         (void) puts("OUT OF MEMORY");
102                         exit(1);
103                 }
104                 sp->file->index = sp - SHIP(0);
105                 sp->file->stern = nat[sp->nationality]++;
106                 sp->file->dir = sp->shipdir;
107                 sp->file->row = sp->shiprow;
108                 sp->file->col = sp->shipcol;
109         }
110         windspeed = cc->windspeed;
111         winddir = cc->winddir;
112
113         (void) signal(SIGHUP, choke);
114         (void) signal(SIGINT, choke);
115
116         hasdriver = sync_exists(game);
117         if (sync_open() < 0) {
118                 perror("sail: syncfile");
119                 exit(1);
120         }
121
122         if (hasdriver) {
123                 (void) puts("Synchronizing with the other players...");
124                 (void) fflush(stdout);
125                 if (Sync() < 0)
126                         leave(LEAVE_SYNC);
127         }
128         for (;;) {
129                 foreachship(sp)
130                         if (sp->file->captain[0] == 0 && !sp->file->struck
131                             && sp->file->captured == 0)
132                                 break;
133                 if (sp >= ls) {
134                         (void) puts("All ships taken in that scenario.");
135                         foreachship(sp)
136                                 free((char *)sp->file);
137                         sync_close(0);
138                         people = 0;
139                         goto reprint;
140                 }
141                 if (randomize) {
142                         player = sp - SHIP(0);
143                 } else {
144                         printf("%s\n\n", cc->name);
145                         foreachship(sp)
146                                 printf("  %2d:  %-10s %-15s  (%-2d pts)   %s\n",
147                                         sp->file->index,
148                                         countryname[sp->nationality],
149                                         sp->shipname,
150                                         sp->specs->pts,
151                                         saywhat(sp, 1));
152                         printf("\nWhich ship (0-%d)? ", cc->vessels-1);
153                         (void) fflush(stdout);
154                         if (scanf("%d", &player) != 1 || player < 0
155                             || player >= cc->vessels) {
156                                 while (getchar() != '\n')
157                                         ;
158                                 (void) puts("Say what?");
159                                 player = -1;
160                         } else
161                                 while (getchar() != '\n')
162                                         ;
163                 }
164                 if (player < 0)
165                         continue;
166                 if (Sync() < 0)
167                         leave(LEAVE_SYNC);
168                 fp = SHIP(player)->file;
169                 if (fp->captain[0] || fp->struck || fp->captured != 0)
170                         (void) puts("That ship is taken.");
171                 else
172                         break;
173         }
174
175         ms = SHIP(player);
176         mf = ms->file;
177         mc = ms->specs;
178
179         Write(W_BEGIN, ms, 0, 0, 0, 0, 0);
180         if (Sync() < 0)
181                 leave(LEAVE_SYNC);
182
183         (void) signal(SIGCHLD, child);
184         if (!hasdriver)
185                 switch (fork()) {
186                 case 0:
187                         longjmp(restart, MODE_DRIVER);
188                         /*NOTREACHED*/
189                 case -1:
190                         perror("fork");
191                         leave(LEAVE_FORK);
192                         break;
193                 default:
194                         hasdriver++;
195                 }
196
197         printf("Your ship is the %s, a %d gun %s (%s crew).\n",
198                 ms->shipname, mc->guns, classname[mc->class],
199                 qualname[mc->qual]);
200         if ((nameptr = (char *) getenv("SAILNAME")) && *nameptr)
201                 (void) strncpy(captain, nameptr, sizeof captain);
202         else {
203                 (void) printf("Your name, Captain? ");
204                 (void) fflush(stdout);
205                 (void) fgets(captain, sizeof captain, stdin);
206                 if (!*captain)
207                         (void) strcpy(captain, "no name");
208                 else
209                         captain[sizeof(captain) - 1] = '\0';
210         }
211         Write(W_CAPTAIN, ms, 1, (long)captain, 0, 0, 0);
212         for (n = 0; n < 2; n++) {
213                 char buf[10];
214
215                 printf("\nInitial broadside %s (grape, chain, round, double): ",
216                         n ? "right" : "left");
217                 (void) fflush(stdout);
218                 (void) scanf("%9s", buf);
219                 switch (*buf) {
220                 case 'g':
221                         load = L_GRAPE;
222                         break;
223                 case 'c':
224                         load = L_CHAIN;
225                         break;
226                 case 'r':
227                         load = L_ROUND;
228                         break;
229                 case 'd':
230                         load = L_DOUBLE;
231                         break;
232                 default:
233                         load = L_ROUND;
234                 }
235                 if (n) {
236                         mf->loadR = load;
237                         mf->readyR = R_LOADED|R_INITIAL;
238                 } else {
239                         mf->loadL = load;
240                         mf->readyL = R_LOADED|R_INITIAL;
241                 }
242         }
243
244         initscreen();
245         draw_board();
246         (void) sprintf(message, "Captain %s assuming command", captain);
247         Write(W_SIGNAL, ms, 1, (long)message, 0, 0, 0);
248         newturn();
249 }