Mercurial > hg > early-roguelike
comparison rogue3/save.c @ 0:527e2150eaf0
Import Rogue 3.6 from the Roguelike Restoration Project (r1490)
| author | edwarj4 |
|---|---|
| date | Tue, 13 Oct 2009 13:33:34 +0000 |
| parents | |
| children | b4856d4d4c4e |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:527e2150eaf0 |
|---|---|
| 1 /* | |
| 2 * save and restore routines | |
| 3 * | |
| 4 * @(#)save.c 3.9 (Berkeley) 6/16/81 | |
| 5 * | |
| 6 * Rogue: Exploring the Dungeons of Doom | |
| 7 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
| 8 * All rights reserved. | |
| 9 * | |
| 10 * See the file LICENSE.TXT for full copyright and licensing information. | |
| 11 */ | |
| 12 | |
| 13 #include "curses.h" | |
| 14 #include <ctype.h> | |
| 15 #include <sys/types.h> | |
| 16 #include <sys/stat.h> | |
| 17 #include <signal.h> | |
| 18 #include <errno.h> | |
| 19 #include <string.h> | |
| 20 #include <stdlib.h> | |
| 21 #include "machdep.h" | |
| 22 #include "rogue.h" | |
| 23 | |
| 24 typedef struct stat STAT; | |
| 25 | |
| 26 extern char version[], encstr[]; | |
| 27 | |
| 28 STAT sbuf; | |
| 29 | |
| 30 int | |
| 31 save_game() | |
| 32 { | |
| 33 FILE *savef; | |
| 34 int c; | |
| 35 char buf[80]; | |
| 36 | |
| 37 /* | |
| 38 * get file name | |
| 39 */ | |
| 40 mpos = 0; | |
| 41 if (file_name[0] != '\0') | |
| 42 { | |
| 43 msg("Save file (%s)? ", file_name); | |
| 44 do | |
| 45 { | |
| 46 c = readchar(cw); | |
| 47 } while (c != 'n' && c != 'N' && c != 'y' && c != 'Y'); | |
| 48 mpos = 0; | |
| 49 if (c == 'y' || c == 'Y') | |
| 50 { | |
| 51 msg("File name: %s", file_name); | |
| 52 goto gotfile; | |
| 53 } | |
| 54 } | |
| 55 | |
| 56 do | |
| 57 { | |
| 58 msg("File name: "); | |
| 59 mpos = 0; | |
| 60 buf[0] = '\0'; | |
| 61 if (get_str(buf, cw) == QUIT) | |
| 62 { | |
| 63 msg(""); | |
| 64 return FALSE; | |
| 65 } | |
| 66 strcpy(file_name, buf); | |
| 67 gotfile: | |
| 68 if ((savef = fopen(file_name, "w")) == NULL) | |
| 69 msg(strerror(errno)); /* fake perror() */ | |
| 70 } while (savef == NULL); | |
| 71 | |
| 72 /* | |
| 73 * write out encrpyted file (after a stat) | |
| 74 * The fwrite is to force allocation of the buffer before the write | |
| 75 */ | |
| 76 if (save_file(savef) != 0) | |
| 77 { | |
| 78 msg("Save game failed!"); | |
| 79 return FALSE; | |
| 80 } | |
| 81 return TRUE; | |
| 82 } | |
| 83 | |
| 84 /* | |
| 85 * automatically save a file. This is used if a HUP signal is | |
| 86 * recieved | |
| 87 */ | |
| 88 void | |
| 89 auto_save(int p) | |
| 90 { | |
| 91 FILE *savef; | |
| 92 int i; | |
| 93 | |
| 94 for (i = 0; i < NSIG; i++) | |
| 95 signal(i, SIG_IGN); | |
| 96 if (file_name[0] != '\0' && (savef = fopen(file_name, "w")) != NULL) | |
| 97 save_file(savef); | |
| 98 endwin(); | |
| 99 exit(1); | |
| 100 } | |
| 101 | |
| 102 /* | |
| 103 * write the saved game on the file | |
| 104 */ | |
| 105 int | |
| 106 save_file(FILE *savef) | |
| 107 { | |
| 108 char buf[80]; | |
| 109 int ret; | |
| 110 | |
| 111 wmove(cw, LINES-1, 0); | |
| 112 draw(cw); | |
| 113 (void) fseek(savef, 0L, 0); | |
| 114 | |
| 115 memset(buf,0,80); | |
| 116 strcpy(buf,version); | |
| 117 encwrite(buf,80,savef); | |
| 118 memset(buf,0,80); | |
| 119 strcpy(buf,"R36 2\n"); | |
| 120 encwrite(buf,80,savef); | |
| 121 memset(buf,0,80); | |
| 122 sprintf(buf,"%d x %d\n", LINES, COLS); | |
| 123 encwrite(buf,80,savef); | |
| 124 | |
| 125 ret = rs_save_file(savef); | |
| 126 | |
| 127 fclose(savef); | |
| 128 | |
| 129 return(ret); | |
| 130 } | |
| 131 | |
| 132 int | |
| 133 restore(char *file, char **envp) | |
| 134 { | |
| 135 FILE *inf; | |
| 136 extern char **environ; | |
| 137 char buf[80]; | |
| 138 int slines, scols; | |
| 139 int rogue_version = 0, savefile_version = 0; | |
| 140 | |
| 141 if (strcmp(file, "-r") == 0) | |
| 142 file = file_name; | |
| 143 | |
| 144 if ((inf = fopen(file, "r")) == NULL) | |
| 145 { | |
| 146 perror(file); | |
| 147 return FALSE; | |
| 148 } | |
| 149 | |
| 150 fflush(stdout); | |
| 151 encread(buf, 80, inf); | |
| 152 | |
| 153 if (strcmp(buf, version) != 0) | |
| 154 { | |
| 155 printf("Sorry, saved game is out of date.\n"); | |
| 156 return FALSE; | |
| 157 } | |
| 158 | |
| 159 encread(buf, 80, inf); | |
| 160 (void) sscanf(buf, "R%d %d\n", &rogue_version, &savefile_version); | |
| 161 | |
| 162 if ((rogue_version != 36) && (savefile_version != 2)) | |
| 163 { | |
| 164 printf("Sorry, saved game format is out of date.\n"); | |
| 165 return FALSE; | |
| 166 } | |
| 167 | |
| 168 encread(buf,80,inf); | |
| 169 (void) sscanf(buf,"%d x %d\n",&slines, &scols); | |
| 170 | |
| 171 /* | |
| 172 * we do not close the file so that we will have a hold of the | |
| 173 * inode for as long as possible | |
| 174 */ | |
| 175 | |
| 176 initscr(); | |
| 177 | |
| 178 if (slines > LINES) | |
| 179 { | |
| 180 endwin(); | |
| 181 printf("Sorry, original game was played on a screen with %d lines.\n",slines); | |
| 182 printf("Current screen only has %d lines. Unable to restore game\n",LINES); | |
| 183 return(FALSE); | |
| 184 } | |
| 185 | |
| 186 if (scols > COLS) | |
| 187 { | |
| 188 endwin(); | |
| 189 printf("Sorry, original game was played on a screen with %d columns.\n",scols); | |
| 190 printf("Current screen only has %d columns. Unable to restore game\n",COLS); | |
| 191 return(FALSE); | |
| 192 } | |
| 193 | |
| 194 cw = newwin(LINES, COLS, 0, 0); | |
| 195 mw = newwin(LINES, COLS, 0, 0); | |
| 196 hw = newwin(LINES, COLS, 0, 0); | |
| 197 nocrmode(); | |
| 198 keypad(cw,1); | |
| 199 mpos = 0; | |
| 200 mvwprintw(cw, 0, 0, "%s", file); | |
| 201 | |
| 202 if (rs_restore_file(inf) != 0) | |
| 203 { | |
| 204 endwin(); | |
| 205 printf("Cannot restore file\n"); | |
| 206 return(FALSE); | |
| 207 } | |
| 208 | |
| 209 if (!wizard && (md_unlink_open_file(file, inf) < 0)) | |
| 210 { | |
| 211 endwin(); | |
| 212 printf("Cannot unlink file\n"); | |
| 213 return FALSE; | |
| 214 } | |
| 215 | |
| 216 environ = envp; | |
| 217 strcpy(file_name, file); | |
| 218 setup(); | |
| 219 clearok(curscr, TRUE); | |
| 220 touchwin(cw); | |
| 221 srand(md_getpid()); | |
| 222 status(); | |
| 223 playit(); | |
| 224 /*NOTREACHED*/ | |
| 225 return(0); | |
| 226 } | |
| 227 | |
| 228 static int encerrno = 0; | |
| 229 | |
| 230 int | |
| 231 encerror() | |
| 232 { | |
| 233 return encerrno; | |
| 234 } | |
| 235 | |
| 236 void | |
| 237 encseterr(int err) | |
| 238 { | |
| 239 encerrno = err; | |
| 240 } | |
| 241 | |
| 242 int | |
| 243 encclearerr() | |
| 244 { | |
| 245 int n = encerrno; | |
| 246 | |
| 247 encerrno = 0; | |
| 248 | |
| 249 return(n); | |
| 250 } | |
| 251 | |
| 252 /* | |
| 253 * perform an encrypted write | |
| 254 */ | |
| 255 size_t | |
| 256 encwrite(const void *buf, size_t size, FILE *outf) | |
| 257 { | |
| 258 char *ep; | |
| 259 const char *start = buf; | |
| 260 size_t o_size = size; | |
| 261 ep = encstr; | |
| 262 | |
| 263 while (size) | |
| 264 { | |
| 265 if (putc(*start++ ^ *ep++, outf) == EOF) | |
| 266 return(o_size - size); | |
| 267 if (*ep == '\0') | |
| 268 ep = encstr; | |
| 269 size--; | |
| 270 } | |
| 271 | |
| 272 return(o_size - size); | |
| 273 } | |
| 274 | |
| 275 /* | |
| 276 * perform an encrypted read | |
| 277 */ | |
| 278 size_t | |
| 279 encread(void *buf, size_t size, FILE *inf) | |
| 280 { | |
| 281 char *ep; | |
| 282 size_t read_size; | |
| 283 char *start = buf; | |
| 284 | |
| 285 if ((read_size = fread(start,1,size,inf)) == 0) | |
| 286 return 0; | |
| 287 | |
| 288 ep = encstr; | |
| 289 | |
| 290 while (size--) | |
| 291 { | |
| 292 *start++ ^= *ep++; | |
| 293 if (*ep == '\0') | |
| 294 ep = encstr; | |
| 295 } | |
| 296 return read_size; | |
| 297 } |
