xref: /openbsd/games/robots/main.c (revision 891d7ab6)
1 /*	$OpenBSD: main.c,v 1.17 2009/10/27 23:59:26 deraadt Exp $	*/
2 /*	$NetBSD: main.c,v 1.5 1995/04/22 10:08:54 cgd 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	"robots.h"
34 
35 void
36 usage(void)
37 {
38 	fprintf(stderr, "usage: robots [-ajrst] [scorefile]\n");
39 	exit(1);
40 }
41 
42 int
43 main(int ac, char *av[])
44 {
45 	bool		show_only;
46 	extern char	*Scorefile;
47 	int		score_wfd;     /* high score writable file descriptor */
48 	int		score_err = 0; /* hold errno from score file open */
49 	int		ch;
50 	extern int	optind;
51 	gid_t		gid;
52 #ifdef FANCY
53 	char		*sp;
54 #endif
55 
56 	if ((score_wfd = open(Scorefile, O_RDWR)) < 0)
57 		score_err = errno;
58 
59 	/* revoke privs */
60 	gid = getgid();
61 	setresgid(gid, gid, gid);
62 
63 	show_only = FALSE;
64 	while ((ch = getopt(ac, av, "srajt")) != -1)
65 		switch (ch) {
66 		case 's':
67 			show_only = TRUE;
68 			break;
69 		case 'r':
70 			Real_time = TRUE;
71 			/* Could be a command-line option */
72 			tv.tv_sec = 3;
73 			tv.tv_usec = 0;
74 			FD_ZERO(&rset);
75 			break;
76 		case 'a':
77 			Start_level = 4;
78 			break;
79 		case 'j':
80 			Jump = TRUE;
81 			break;
82 		case 't':
83 			Teleport = TRUE;
84 			break;
85 		case '?':
86 		default:
87 			usage();
88 		}
89 	ac -= optind;
90 	av += optind;
91 
92 	if (ac > 1)
93 		usage();
94 	if (ac == 1) {
95 		Scorefile = av[0];
96 		if (score_wfd >= 0)
97 			close(score_wfd);
98 		/* This file requires no special privileges. */
99 		if ((score_wfd = open(Scorefile, O_RDWR)) < 0)
100 			score_err = errno;
101 #ifdef	FANCY
102 		sp = strrchr(Scorefile, '/');
103 		if (sp == NULL)
104 			sp = Scorefile;
105 		if (strcmp(sp, "pattern_roll") == 0)
106 			Pattern_roll = TRUE;
107 		else if (strcmp(sp, "stand_still") == 0)
108 			Stand_still = TRUE;
109 		if (Pattern_roll || Stand_still)
110 			Teleport = TRUE;
111 #endif
112 	}
113 
114 	if (show_only) {
115 		show_score();
116 		exit(0);
117 	}
118 
119 	if (score_wfd < 0) {
120 		warnx("%s: %s; no scores will be saved", Scorefile,
121 			strerror(score_err));
122 		sleep(1);
123 	}
124 
125 	initscr();
126 	signal(SIGINT, quit);
127 	cbreak();
128 	noecho();
129 	nonl();
130 	if (LINES != Y_SIZE || COLS != X_SIZE) {
131 		if (LINES < Y_SIZE || COLS < X_SIZE) {
132 			endwin();
133 			errx(1, "Need at least a %dx%d screen", Y_SIZE, X_SIZE);
134 		}
135 		delwin(stdscr);
136 		stdscr = newwin(Y_SIZE, X_SIZE, 0, 0);
137 	}
138 
139 	srandomdev();
140 	do {
141 		init_field();
142 		for (Level = Start_level; !Dead; Level++) {
143 			make_level();
144 			play_level();
145 		}
146 		move(My_pos.y, My_pos.x);
147 		printw("AARRrrgghhhh....");
148 		refresh();
149 		score(score_wfd);
150 	} while (another());
151 	quit(0);
152 	/* NOT REACHED */
153 }
154 
155 /*
156  * quit:
157  *	Leave the program elegantly.
158  */
159 void
160 quit(int dummy)
161 {
162 	endwin();
163 	exit(0);
164 }
165 
166 /*
167  * another:
168  *	See if another game is desired
169  */
170 bool
171 another(void)
172 {
173 	int	y;
174 
175 #ifdef	FANCY
176 	if ((Stand_still || Pattern_roll) && !Newscore)
177 		return TRUE;
178 #endif
179 
180 	if (query("Another game?")) {
181 		if (Full_clear) {
182 			for (y = 1; y <= Num_scores; y++) {
183 				move(y, 1);
184 				clrtoeol();
185 			}
186 			refresh();
187 		}
188 		return TRUE;
189 	}
190 	return FALSE;
191 }
192