1*d7259957Scheloha /* $OpenBSD: main.c,v 1.31 2022/12/04 23:50:45 cheloha Exp $ */
2df930be7Sderaadt /* $NetBSD: main.c,v 1.5 1995/04/22 10:08:54 cgd Exp $ */
3df930be7Sderaadt
4df930be7Sderaadt /*
5df930be7Sderaadt * Copyright (c) 1980, 1993
6df930be7Sderaadt * The Regents of the University of California. All rights reserved.
7df930be7Sderaadt *
8df930be7Sderaadt * Redistribution and use in source and binary forms, with or without
9df930be7Sderaadt * modification, are permitted provided that the following conditions
10df930be7Sderaadt * are met:
11df930be7Sderaadt * 1. Redistributions of source code must retain the above copyright
12df930be7Sderaadt * notice, this list of conditions and the following disclaimer.
13df930be7Sderaadt * 2. Redistributions in binary form must reproduce the above copyright
14df930be7Sderaadt * notice, this list of conditions and the following disclaimer in the
15df930be7Sderaadt * documentation and/or other materials provided with the distribution.
167a09557bSmillert * 3. Neither the name of the University nor the names of its contributors
17df930be7Sderaadt * may be used to endorse or promote products derived from this software
18df930be7Sderaadt * without specific prior written permission.
19df930be7Sderaadt *
20df930be7Sderaadt * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21df930be7Sderaadt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22df930be7Sderaadt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23df930be7Sderaadt * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24df930be7Sderaadt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25df930be7Sderaadt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26df930be7Sderaadt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27df930be7Sderaadt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28df930be7Sderaadt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29df930be7Sderaadt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30df930be7Sderaadt * SUCH DAMAGE.
31df930be7Sderaadt */
32df930be7Sderaadt
332010f3c8Smestre #include <err.h>
342010f3c8Smestre #include <errno.h>
352010f3c8Smestre #include <fcntl.h>
362010f3c8Smestre #include <signal.h>
372010f3c8Smestre #include <stdlib.h>
382010f3c8Smestre #include <string.h>
392010f3c8Smestre #include <unistd.h>
402010f3c8Smestre
41df930be7Sderaadt #include "robots.h"
42df930be7Sderaadt
434c144bbcSpjanzen void
usage(void)443eb8c9edSjsg usage(void)
454c144bbcSpjanzen {
466fa5e1daSmestre fprintf(stderr, "usage: %s [-ajrst] [scorefile]\n", getprogname());
474c144bbcSpjanzen exit(1);
484c144bbcSpjanzen }
494c144bbcSpjanzen
50d648d61bSpjanzen int
main(int ac,char * av[])513eb8c9edSjsg main(int ac, char *av[])
52df930be7Sderaadt {
5397419aa0Spjanzen bool show_only;
54e224588fStb extern char Scorefile[PATH_MAX];
555f463f57Skstailey int score_wfd; /* high score writable file descriptor */
56d648d61bSpjanzen int score_err = 0; /* hold errno from score file open */
574c144bbcSpjanzen int ch;
58e224588fStb int ret;
59e224588fStb char *home;
604c144bbcSpjanzen #ifdef FANCY
6197419aa0Spjanzen char *sp;
624c144bbcSpjanzen #endif
63df930be7Sderaadt
64e224588fStb home = getenv("HOME");
65e224588fStb if (home == NULL || *home == '\0')
66e224588fStb err(1, "getenv");
67e224588fStb
68e224588fStb ret = snprintf(Scorefile, sizeof(Scorefile), "%s/%s", home,
69e224588fStb ".robots.scores");
70e224588fStb if (ret < 0 || ret >= PATH_MAX)
71e224588fStb errc(1, ENAMETOOLONG, "%s/%s", home, ".robots.scores");
72e224588fStb
73df69c215Sderaadt if ((score_wfd = open(Scorefile, O_RDWR | O_CREAT, 0666)) == -1)
74e224588fStb score_err = errno;
75161033a1Sderaadt
76df930be7Sderaadt show_only = FALSE;
774c144bbcSpjanzen while ((ch = getopt(ac, av, "srajt")) != -1)
784c144bbcSpjanzen switch (ch) {
794c144bbcSpjanzen case 's':
804c144bbcSpjanzen show_only = TRUE;
814c144bbcSpjanzen break;
824c144bbcSpjanzen case 'r':
834c144bbcSpjanzen Real_time = TRUE;
844c144bbcSpjanzen /* Could be a command-line option */
854c144bbcSpjanzen tv.tv_sec = 3;
864c144bbcSpjanzen break;
874c144bbcSpjanzen case 'a':
884c144bbcSpjanzen Start_level = 4;
894c144bbcSpjanzen break;
904c144bbcSpjanzen case 'j':
914c144bbcSpjanzen Jump = TRUE;
924c144bbcSpjanzen break;
934c144bbcSpjanzen case 't':
944c144bbcSpjanzen Teleport = TRUE;
954c144bbcSpjanzen break;
964c144bbcSpjanzen default:
974c144bbcSpjanzen usage();
984c144bbcSpjanzen }
994c144bbcSpjanzen ac -= optind;
1004c144bbcSpjanzen av += optind;
1014c144bbcSpjanzen
1024c144bbcSpjanzen if (ac > 1)
1034c144bbcSpjanzen usage();
1044c144bbcSpjanzen if (ac == 1) {
105e224588fStb if (strlcpy(Scorefile, av[0], sizeof(Scorefile)) >=
106e224588fStb sizeof(Scorefile))
107e224588fStb errc(1, ENAMETOOLONG, "%s", av[0]);
108d648d61bSpjanzen if (score_wfd >= 0)
1095f463f57Skstailey close(score_wfd);
110fdb7e56cSpjanzen /* This file requires no special privileges. */
111df69c215Sderaadt if ((score_wfd = open(Scorefile, O_RDWR | O_CREAT, 0666)) == -1)
112d648d61bSpjanzen score_err = errno;
113d648d61bSpjanzen #ifdef FANCY
114fdb7e56cSpjanzen sp = strrchr(Scorefile, '/');
115fdb7e56cSpjanzen if (sp == NULL)
116fdb7e56cSpjanzen sp = Scorefile;
117df930be7Sderaadt if (strcmp(sp, "pattern_roll") == 0)
118df930be7Sderaadt Pattern_roll = TRUE;
119df930be7Sderaadt else if (strcmp(sp, "stand_still") == 0)
120df930be7Sderaadt Stand_still = TRUE;
121df930be7Sderaadt if (Pattern_roll || Stand_still)
122df930be7Sderaadt Teleport = TRUE;
123df930be7Sderaadt #endif
124df930be7Sderaadt }
125df930be7Sderaadt
126df930be7Sderaadt if (show_only) {
127df930be7Sderaadt show_score();
12817641e31Stb return 0;
129d648d61bSpjanzen }
130d648d61bSpjanzen
1314c144bbcSpjanzen if (score_wfd < 0) {
132fdb7e56cSpjanzen warnx("%s: %s; no scores will be saved", Scorefile,
133fdb7e56cSpjanzen strerror(score_err));
1344c144bbcSpjanzen sleep(1);
1354c144bbcSpjanzen }
136df930be7Sderaadt
137df930be7Sderaadt initscr();
1388ac81e2dSmestre
1398ac81e2dSmestre if (pledge("stdio tty", NULL) == -1)
1408ac81e2dSmestre err(1, "pledge");
1418ac81e2dSmestre
142df930be7Sderaadt signal(SIGINT, quit);
1438c730b5fSpjanzen cbreak();
144df930be7Sderaadt noecho();
145df930be7Sderaadt nonl();
146df930be7Sderaadt if (LINES != Y_SIZE || COLS != X_SIZE) {
147df930be7Sderaadt if (LINES < Y_SIZE || COLS < X_SIZE) {
148df930be7Sderaadt endwin();
149fdb7e56cSpjanzen errx(1, "Need at least a %dx%d screen", Y_SIZE, X_SIZE);
150df930be7Sderaadt }
151df930be7Sderaadt delwin(stdscr);
152df930be7Sderaadt stdscr = newwin(Y_SIZE, X_SIZE, 0, 0);
153df930be7Sderaadt }
154df930be7Sderaadt
155df930be7Sderaadt do {
156df930be7Sderaadt init_field();
157df930be7Sderaadt for (Level = Start_level; !Dead; Level++) {
158df930be7Sderaadt make_level();
159df930be7Sderaadt play_level();
160df930be7Sderaadt }
161ebff5be7Stedu if (My_pos.x > X_FIELDSIZE - 16)
162ebff5be7Stedu move(My_pos.y, X_FIELDSIZE - 16);
163ebff5be7Stedu else
164df930be7Sderaadt move(My_pos.y, My_pos.x);
165df930be7Sderaadt printw("AARRrrgghhhh....");
166df930be7Sderaadt refresh();
1675f463f57Skstailey score(score_wfd);
168df930be7Sderaadt } while (another());
169d648d61bSpjanzen quit(0);
170df930be7Sderaadt }
171df930be7Sderaadt
172df930be7Sderaadt /*
173df930be7Sderaadt * quit:
174df930be7Sderaadt * Leave the program elegantly.
175df930be7Sderaadt */
176df930be7Sderaadt void
quit(int dummy)1773eb8c9edSjsg quit(int dummy)
178df930be7Sderaadt {
179df930be7Sderaadt endwin();
180df930be7Sderaadt exit(0);
181df930be7Sderaadt }
182df930be7Sderaadt
183df930be7Sderaadt /*
184df930be7Sderaadt * another:
185df930be7Sderaadt * See if another game is desired
186df930be7Sderaadt */
187d648d61bSpjanzen bool
another(void)1883eb8c9edSjsg another(void)
189df930be7Sderaadt {
19097419aa0Spjanzen int y;
191df930be7Sderaadt
192df930be7Sderaadt #ifdef FANCY
193df930be7Sderaadt if ((Stand_still || Pattern_roll) && !Newscore)
194df930be7Sderaadt return TRUE;
195df930be7Sderaadt #endif
196df930be7Sderaadt
197df930be7Sderaadt if (query("Another game?")) {
198df930be7Sderaadt if (Full_clear) {
199df930be7Sderaadt for (y = 1; y <= Num_scores; y++) {
200df930be7Sderaadt move(y, 1);
201df930be7Sderaadt clrtoeol();
202df930be7Sderaadt }
203df930be7Sderaadt refresh();
204df930be7Sderaadt }
205df930be7Sderaadt return TRUE;
206df930be7Sderaadt }
207df930be7Sderaadt return FALSE;
208df930be7Sderaadt }
209