Mercurial > hg > early-roguelike
comparison arogue5/save.c @ 63:0ed67132cf10
Import Advanced Rogue 5.8 from the Roguelike Restoration Project (r1490)
| author | elwin | 
|---|---|
| date | Thu, 09 Aug 2012 22:58:48 +0000 | 
| parents | |
| children | a98834ce7e04 | 
   comparison
  equal
  deleted
  inserted
  replaced
| 62:0ef99244acb8 | 63:0ed67132cf10 | 
|---|---|
| 1 /* | |
| 2 * save and restore routines | |
| 3 * | |
| 4 * Advanced Rogue | |
| 5 * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T | |
| 6 * All rights reserved. | |
| 7 * | |
| 8 * Based on "Rogue: Exploring the Dungeons of Doom" | |
| 9 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
| 10 * All rights reserved. | |
| 11 * | |
| 12 * See the file LICENSE.TXT for full copyright and licensing information. | |
| 13 */ | |
| 14 | |
| 15 #include "curses.h" | |
| 16 #include <fcntl.h> | |
| 17 #include <errno.h> | |
| 18 #include <ctype.h> | |
| 19 #include <sys/types.h> | |
| 20 #include <sys/stat.h> | |
| 21 #include <signal.h> | |
| 22 #include "rogue.h" | |
| 23 | |
| 24 typedef struct stat STAT; | |
| 25 | |
| 26 extern char version[], encstr[]; | |
| 27 /* extern bool _endwin; */ | |
| 28 | |
| 29 STAT sbuf; | |
| 30 | |
| 31 bool | |
| 32 save_game() | |
| 33 { | |
| 34 register FILE *savef; | |
| 35 register int c; | |
| 36 char buf[LINELEN]; | |
| 37 | |
| 38 /* | |
| 39 * get file name | |
| 40 */ | |
| 41 mpos = 0; | |
| 42 if (file_name[0] != '\0') | |
| 43 { | |
| 44 msg("Save file (%s)? ", file_name); | |
| 45 do | |
| 46 { | |
| 47 c = readchar(); | |
| 48 if (c == ESCAPE) return(0); | |
| 49 } while (c != 'n' && c != 'N' && c != 'y' && c != 'Y'); | |
| 50 mpos = 0; | |
| 51 if (c == 'y' || c == 'Y') | |
| 52 { | |
| 53 msg("File name: %s", file_name); | |
| 54 goto gotfile; | |
| 55 } | |
| 56 } | |
| 57 | |
| 58 do | |
| 59 { | |
| 60 msg("File name: "); | |
| 61 mpos = 0; | |
| 62 buf[0] = '\0'; | |
| 63 if (get_str(buf, cw) == QUIT) | |
| 64 { | |
| 65 msg(""); | |
| 66 return FALSE; | |
| 67 } | |
| 68 msg(""); | |
| 69 strcpy(file_name, buf); | |
| 70 gotfile: | |
| 71 if ((savef = fopen(file_name, "w")) == NULL) | |
| 72 msg(strerror(errno)); /* fake perror() */ | |
| 73 } while (savef == NULL); | |
| 74 | |
| 75 /* | |
| 76 * write out encrpyted file (after a stat) | |
| 77 * The fwrite is to force allocation of the buffer before the write | |
| 78 */ | |
| 79 if (save_file(savef) != 0) { | |
| 80 msg("Cannot create save file."); | |
| 81 unlink(file_name); | |
| 82 return(FALSE); | |
| 83 } | |
| 84 else return(TRUE); | |
| 85 } | |
| 86 | |
| 87 /* | |
| 88 * automatically save a file. This is used if a HUP signal is | |
| 89 * recieved | |
| 90 */ | |
| 91 void | |
| 92 auto_save(int sig) | |
| 93 { | |
| 94 register FILE *savef; | |
| 95 register int i; | |
| 96 | |
| 97 NOOP(sig); | |
| 98 | |
| 99 for (i = 0; i < NSIG; i++) | |
| 100 signal(i, SIG_IGN); | |
| 101 if (file_name[0] != '\0' && | |
| 102 pstats.s_hpt > 0 && | |
| 103 (savef = fopen(file_name, "w")) != NULL) | |
| 104 save_file(savef); | |
| 105 exit(1); | |
| 106 } | |
| 107 | |
| 108 /* | |
| 109 * write the saved game on the file | |
| 110 */ | |
| 111 bool | |
| 112 save_file(savef) | |
| 113 register FILE *savef; | |
| 114 { | |
| 115 int ret; | |
| 116 int slines = LINES; | |
| 117 int scols = COLS; | |
| 118 | |
| 119 wmove(cw, LINES-1, 0); | |
| 120 draw(cw); | |
| 121 fwrite("junk", 1, 5, savef); | |
| 122 fseek(savef, 0L, 0); | |
| 123 /* _endwin = TRUE; */ | |
| 124 fstat(fileno(savef), &sbuf); | |
| 125 | |
| 126 encwrite(version,strlen(version)+1,savef); | |
| 127 sprintf(prbuf,"%d x %d\n", LINES, COLS); | |
| 128 encwrite(prbuf,80,savef); | |
| 129 | |
| 130 msg(""); | |
| 131 ret = rs_save_file(savef); | |
| 132 | |
| 133 fclose(savef); | |
| 134 | |
| 135 return(ret); | |
| 136 } | |
| 137 | |
| 138 restore(file, envp) | |
| 139 register char *file; | |
| 140 char **envp; | |
| 141 { | |
| 142 register int inf; | |
| 143 #ifndef _AIX | |
| 144 extern char **environ; | |
| 145 #endif | |
| 146 char buf[LINELEN]; | |
| 147 STAT sbuf2; | |
| 148 int oldcol, oldline; /* Old number of columns and lines */ | |
| 149 | |
| 150 if (strcmp(file, "-r") == 0) | |
| 151 file = file_name; | |
| 152 | |
| 153 if ((inf = open(file, O_RDONLY)) < 0) | |
| 154 { | |
| 155 perror(file); | |
| 156 return FALSE; | |
| 157 } | |
| 158 | |
| 159 fflush(stdout); | |
| 160 | |
| 161 encread(buf, strlen(version) + 1, inf); | |
| 162 | |
| 163 if (strcmp(buf, version) != 0) | |
| 164 { | |
| 165 printf("Sorry, saved game is out of date.\n"); | |
| 166 return FALSE; | |
| 167 } | |
| 168 | |
| 169 /* | |
| 170 * Get the lines and columns from the previous game | |
| 171 */ | |
| 172 | |
| 173 encread(buf, 80, inf); | |
| 174 sscanf(buf, "%d x %d\n", &oldline, &oldcol); | |
| 175 fstat(inf, &sbuf2); | |
| 176 fflush(stdout); | |
| 177 | |
| 178 /* | |
| 179 * Set the new terminal and make sure we aren't going to a smaller screen. | |
| 180 */ | |
| 181 | |
| 182 initscr(); | |
| 183 | |
| 184 if (COLS < oldcol || LINES < oldline) { | |
| 185 endwin(); | |
| 186 printf("\nCannot restart the game on a smaller screen.\n"); | |
| 187 return FALSE; | |
| 188 } | |
| 189 | |
| 190 cw = newwin(LINES, COLS, 0, 0); | |
| 191 mw = newwin(LINES, COLS, 0, 0); | |
| 192 hw = newwin(LINES, COLS, 0, 0); | |
| 193 msgw = newwin(4, COLS, 0, 0); | |
| 194 keypad(cw,1); | |
| 195 keypad(msgw,1); | |
| 196 | |
| 197 mpos = 0; | |
| 198 mvwprintw(cw, 0, 0, "%s: %s", file, ctime(&sbuf2.st_mtime)); | |
| 199 | |
| 200 /* | |
| 201 * defeat multiple restarting from the same place | |
| 202 */ | |
| 203 if (!wizard) { | |
| 204 if (sbuf2.st_nlink != 1) { | |
| 205 endwin(); | |
| 206 printf("\nCannot restore from a linked file\n"); | |
| 207 return FALSE; | |
| 208 } | |
| 209 } | |
| 210 | |
| 211 if (rs_restore_file(inf) != 0) | |
| 212 { | |
| 213 endwin(); | |
| 214 printf("\nCannot restore file\n"); | |
| 215 return(FALSE); | |
| 216 } | |
| 217 | |
| 218 if (!wizard) | |
| 219 { | |
| 220 if (unlink(file) < 0) { | |
| 221 close(inf); /* only close if system insists */ | |
| 222 if (unlink(file) < 0) { | |
| 223 endwin(); | |
| 224 printf("\nCannot unlink file\n"); | |
| 225 return FALSE; | |
| 226 } | |
| 227 } | |
| 228 } | |
| 229 | |
| 230 environ = envp; | |
| 231 strcpy(file_name, file); | |
| 232 setup(); | |
| 233 clearok(curscr, TRUE); | |
| 234 touchwin(cw); | |
| 235 srand(getpid()); | |
| 236 playit(); | |
| 237 /*NOTREACHED*/ | |
| 238 return(FALSE); | |
| 239 } | |
| 240 | |
| 241 /* | |
| 242 * perform an encrypted write | |
| 243 */ | |
| 244 encwrite(start, size, outf) | |
| 245 register char *start; | |
| 246 register unsigned size; | |
| 247 register FILE *outf; | |
| 248 { | |
| 249 register char *ep; | |
| 250 register num_written = 0; | |
| 251 | |
| 252 ep = encstr; | |
| 253 | |
| 254 while (size--) | |
| 255 { | |
| 256 if (putc(*start++ ^ *ep++, outf) == EOF && ferror(outf)) | |
| 257 return(num_written); | |
| 258 num_written++; | |
| 259 if (*ep == '\0') | |
| 260 ep = encstr; | |
| 261 } | |
| 262 return(num_written); | |
| 263 } | |
| 264 | |
| 265 /* | |
| 266 * perform an encrypted read | |
| 267 */ | |
| 268 encread(start, size, inf) | |
| 269 register char *start; | |
| 270 register unsigned size; | |
| 271 register int inf; | |
| 272 { | |
| 273 register char *ep; | |
| 274 register int read_size; | |
| 275 | |
| 276 if ((read_size = read(inf, start, size)) == -1 || read_size == 0) | |
| 277 return read_size; | |
| 278 | |
| 279 ep = encstr; | |
| 280 | |
| 281 size = read_size; | |
| 282 while (size--) | |
| 283 { | |
| 284 *start++ ^= *ep++; | |
| 285 if (*ep == '\0') | |
| 286 ep = encstr; | |
| 287 } | |
| 288 return read_size; | |
| 289 } | 
