1 /* $OpenBSD: main.c,v 1.29 2020/02/14 19:17:33 schwarze 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 <err.h> 34 #include <errno.h> 35 #include <fcntl.h> 36 #include <signal.h> 37 #include <stdlib.h> 38 #include <string.h> 39 #include <unistd.h> 40 41 #include "robots.h" 42 43 void 44 usage(void) 45 { 46 fprintf(stderr, "usage: %s [-ajrst] [scorefile]\n", getprogname()); 47 exit(1); 48 } 49 50 int 51 main(int ac, char *av[]) 52 { 53 bool show_only; 54 extern char Scorefile[PATH_MAX]; 55 int score_wfd; /* high score writable file descriptor */ 56 int score_err = 0; /* hold errno from score file open */ 57 int ch; 58 int ret; 59 char *home; 60 #ifdef FANCY 61 char *sp; 62 #endif 63 64 if (pledge("stdio rpath wpath cpath tty", NULL) == -1) 65 err(1, "pledge"); 66 67 home = getenv("HOME"); 68 if (home == NULL || *home == '\0') 69 err(1, "getenv"); 70 71 ret = snprintf(Scorefile, sizeof(Scorefile), "%s/%s", home, 72 ".robots.scores"); 73 if (ret < 0 || ret >= PATH_MAX) 74 errc(1, ENAMETOOLONG, "%s/%s", home, ".robots.scores"); 75 76 if ((score_wfd = open(Scorefile, O_RDWR | O_CREAT, 0666)) == -1) 77 score_err = errno; 78 79 show_only = FALSE; 80 while ((ch = getopt(ac, av, "srajt")) != -1) 81 switch (ch) { 82 case 's': 83 show_only = TRUE; 84 break; 85 case 'r': 86 Real_time = TRUE; 87 /* Could be a command-line option */ 88 tv.tv_sec = 3; 89 break; 90 case 'a': 91 Start_level = 4; 92 break; 93 case 'j': 94 Jump = TRUE; 95 break; 96 case 't': 97 Teleport = TRUE; 98 break; 99 case '?': 100 default: 101 usage(); 102 } 103 ac -= optind; 104 av += optind; 105 106 if (ac > 1) 107 usage(); 108 if (ac == 1) { 109 if (strlcpy(Scorefile, av[0], sizeof(Scorefile)) >= 110 sizeof(Scorefile)) 111 errc(1, ENAMETOOLONG, "%s", av[0]); 112 if (score_wfd >= 0) 113 close(score_wfd); 114 /* This file requires no special privileges. */ 115 if ((score_wfd = open(Scorefile, O_RDWR | O_CREAT, 0666)) == -1) 116 score_err = errno; 117 #ifdef FANCY 118 sp = strrchr(Scorefile, '/'); 119 if (sp == NULL) 120 sp = Scorefile; 121 if (strcmp(sp, "pattern_roll") == 0) 122 Pattern_roll = TRUE; 123 else if (strcmp(sp, "stand_still") == 0) 124 Stand_still = TRUE; 125 if (Pattern_roll || Stand_still) 126 Teleport = TRUE; 127 #endif 128 } 129 130 if (show_only) { 131 show_score(); 132 return 0; 133 } 134 135 if (score_wfd < 0) { 136 warnx("%s: %s; no scores will be saved", Scorefile, 137 strerror(score_err)); 138 sleep(1); 139 } 140 141 initscr(); 142 143 if (pledge("stdio tty", NULL) == -1) 144 err(1, "pledge"); 145 146 signal(SIGINT, quit); 147 cbreak(); 148 noecho(); 149 nonl(); 150 if (LINES != Y_SIZE || COLS != X_SIZE) { 151 if (LINES < Y_SIZE || COLS < X_SIZE) { 152 endwin(); 153 errx(1, "Need at least a %dx%d screen", Y_SIZE, X_SIZE); 154 } 155 delwin(stdscr); 156 stdscr = newwin(Y_SIZE, X_SIZE, 0, 0); 157 } 158 159 do { 160 init_field(); 161 for (Level = Start_level; !Dead; Level++) { 162 make_level(); 163 play_level(); 164 } 165 if (My_pos.x > X_FIELDSIZE - 16) 166 move(My_pos.y, X_FIELDSIZE - 16); 167 else 168 move(My_pos.y, My_pos.x); 169 printw("AARRrrgghhhh...."); 170 refresh(); 171 score(score_wfd); 172 } while (another()); 173 quit(0); 174 } 175 176 /* 177 * quit: 178 * Leave the program elegantly. 179 */ 180 void 181 quit(int dummy) 182 { 183 endwin(); 184 exit(0); 185 } 186 187 /* 188 * another: 189 * See if another game is desired 190 */ 191 bool 192 another(void) 193 { 194 int y; 195 196 #ifdef FANCY 197 if ((Stand_still || Pattern_roll) && !Newscore) 198 return TRUE; 199 #endif 200 201 if (query("Another game?")) { 202 if (Full_clear) { 203 for (y = 1; y <= Num_scores; y++) { 204 move(y, 1); 205 clrtoeol(); 206 } 207 refresh(); 208 } 209 return TRUE; 210 } 211 return FALSE; 212 } 213