Mercurial > hg > early-roguelike
comparison rogue5/save.c @ 33:f502bf60e6e4
Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
author | elwin |
---|---|
date | Mon, 24 May 2010 20:10:59 +0000 |
parents | |
children | 655c317b6237 |
comparison
equal
deleted
inserted
replaced
32:2dcd75e6a736 | 33:f502bf60e6e4 |
---|---|
1 /* | |
2 * save and restore routines | |
3 * | |
4 * @(#)save.c 4.33 (Berkeley) 06/01/83 | |
5 * | |
6 * Rogue: Exploring the Dungeons of Doom | |
7 * Copyright (C) 1980-1983, 1985, 1999 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 <stdlib.h> | |
14 #include <sys/types.h> | |
15 #include <sys/stat.h> | |
16 #include <errno.h> | |
17 #include <signal.h> | |
18 #include <string.h> | |
19 #include <curses.h> | |
20 #include "rogue.h" | |
21 #include "score.h" | |
22 | |
23 /* | |
24 * save_game: | |
25 * Implement the "save game" command | |
26 */ | |
27 | |
28 void | |
29 save_game(void) | |
30 { | |
31 FILE *savef; | |
32 int c; | |
33 char buf[MAXSTR]; | |
34 struct stat sbuf; | |
35 /* | |
36 * get file name | |
37 */ | |
38 mpos = 0; | |
39 over: | |
40 if (file_name[0] != '\0') | |
41 { | |
42 for (;;) | |
43 { | |
44 msg("save file (%s)? ", file_name); | |
45 c = readchar(); | |
46 mpos = 0; | |
47 if (c == ESCAPE) | |
48 { | |
49 msg(""); | |
50 return; | |
51 } | |
52 else if (c == 'n' || c == 'N' || c == 'y' || c == 'Y') | |
53 break; | |
54 else | |
55 msg("please answer Y or N"); | |
56 } | |
57 if (c == 'y' || c == 'Y') | |
58 { | |
59 addstr("Yes\n"); | |
60 refresh(); | |
61 strcpy(buf, file_name); | |
62 goto gotfile; | |
63 } | |
64 } | |
65 | |
66 do | |
67 { | |
68 mpos = 0; | |
69 msg("file name: "); | |
70 buf[0] = '\0'; | |
71 if (get_str(buf, stdscr) == QUIT) | |
72 { | |
73 quit_it: | |
74 msg(""); | |
75 return; | |
76 } | |
77 mpos = 0; | |
78 gotfile: | |
79 /* | |
80 * test to see if the file exists | |
81 */ | |
82 if (stat(buf, &sbuf) >= 0) | |
83 { | |
84 for (;;) | |
85 { | |
86 msg("File exists. Do you wish to overwrite it?"); | |
87 mpos = 0; | |
88 if ((c = readchar()) == ESCAPE) | |
89 goto quit_it; | |
90 if (c == 'y' || c == 'Y') | |
91 break; | |
92 else if (c == 'n' || c == 'N') | |
93 goto over; | |
94 else | |
95 msg("Please answer Y or N"); | |
96 } | |
97 msg("file name: %s", buf); | |
98 md_unlink(file_name); | |
99 } | |
100 strcpy(file_name, buf); | |
101 if ((savef = fopen(file_name, "w")) == NULL) | |
102 msg(strerror(errno)); | |
103 } while (savef == NULL); | |
104 msg(""); | |
105 save_file(savef); | |
106 /* NOTREACHED */ | |
107 } | |
108 | |
109 /* | |
110 * auto_save: | |
111 * Automatically save a file. This is used if a HUP signal is | |
112 * recieved | |
113 */ | |
114 | |
115 void | |
116 auto_save(int sig) | |
117 { | |
118 FILE *savef; | |
119 NOOP(sig); | |
120 | |
121 md_ignoreallsignals(); | |
122 if (file_name[0] != '\0' && ((savef = fopen(file_name, "w")) != NULL || | |
123 (md_unlink_open_file(file_name, savef) >= 0 && (savef = fopen(file_name, "w")) != NULL))) | |
124 save_file(savef); | |
125 exit(0); | |
126 } | |
127 | |
128 /* | |
129 * save_file: | |
130 * Write the saved game on the file | |
131 */ | |
132 | |
133 void | |
134 save_file(FILE *savef) | |
135 { | |
136 char buf[80]; | |
137 mvcur(0, COLS - 1, LINES - 1, 0); | |
138 putchar('\n'); | |
139 endwin(); | |
140 resetltchars(); | |
141 md_chmod(file_name, 0400); | |
142 encwrite(version, strlen(version)+1, savef); | |
143 sprintf(buf,"%d x %d\n", LINES, COLS); | |
144 encwrite(buf,80,savef); | |
145 rs_save_file(savef); | |
146 fflush(savef); | |
147 fclose(savef); | |
148 exit(0); | |
149 } | |
150 | |
151 /* | |
152 * restore: | |
153 * Restore a saved game from a file with elaborate checks for file | |
154 * integrity from cheaters | |
155 */ | |
156 int | |
157 restore(const char *file) | |
158 { | |
159 FILE *inf; | |
160 int syml; | |
161 char buf[MAXSTR]; | |
162 struct stat sbuf2; | |
163 int lines, cols; | |
164 | |
165 if (strcmp(file, "-r") == 0) | |
166 file = file_name; | |
167 | |
168 md_tstphold(); | |
169 | |
170 if ((inf = fopen(file,"r")) == NULL) | |
171 { | |
172 perror(file); | |
173 return FALSE; | |
174 } | |
175 stat(file, &sbuf2); | |
176 syml = is_symlink(file); | |
177 | |
178 fflush(stdout); | |
179 encread(buf, strlen(version) + 1, inf); | |
180 if (strcmp(buf, version) != 0) | |
181 { | |
182 printf("Sorry, saved game is out of date.\n"); | |
183 return FALSE; | |
184 } | |
185 encread(buf,80,inf); | |
186 (void) sscanf(buf,"%d x %d\n", &lines, &cols); | |
187 | |
188 initscr(); /* Start up cursor package */ | |
189 keypad(stdscr, 1); | |
190 | |
191 if (lines > LINES) | |
192 { | |
193 endwin(); | |
194 printf("Sorry, original game was played on a screen with %d lines.\n",lines); | |
195 printf("Current screen only has %d lines. Unable to restore game\n",LINES); | |
196 return(FALSE); | |
197 } | |
198 if (cols > COLS) | |
199 { | |
200 endwin(); | |
201 printf("Sorry, original game was played on a screen with %d columns.\n",cols); | |
202 printf("Current screen only has %d columns. Unable to restore game\n",COLS); | |
203 return(FALSE); | |
204 } | |
205 | |
206 hw = newwin(LINES, COLS, 0, 0); | |
207 setup(); | |
208 | |
209 rs_restore_file(inf); | |
210 /* | |
211 * we do not close the file so that we will have a hold of the | |
212 * inode for as long as possible | |
213 */ | |
214 | |
215 if ( | |
216 #ifdef MASTER | |
217 !wizard && | |
218 #endif | |
219 md_unlink_open_file(file, inf) < 0) | |
220 { | |
221 printf("Cannot unlink file\n"); | |
222 return FALSE; | |
223 } | |
224 mpos = 0; | |
225 /* printw(0, 0, "%s: %s", file, ctime(&sbuf2.st_mtime)); */ | |
226 /* | |
227 printw("%s: %s", file, ctime(&sbuf2.st_mtime)); | |
228 */ | |
229 clearok(stdscr,TRUE); | |
230 /* | |
231 * defeat multiple restarting from the same place | |
232 */ | |
233 #ifdef MASTER | |
234 if (!wizard) | |
235 #endif | |
236 if (sbuf2.st_nlink != 1 || syml) | |
237 { | |
238 endwin(); | |
239 printf("\nCannot restore from a linked file\n"); | |
240 return FALSE; | |
241 } | |
242 | |
243 if (pstats.s_hpt <= 0) | |
244 { | |
245 endwin(); | |
246 printf("\n\"He's dead, Jim\"\n"); | |
247 return FALSE; | |
248 } | |
249 | |
250 md_tstpresume(); | |
251 | |
252 strcpy(file_name, file); | |
253 clearok(curscr, TRUE); | |
254 srand(md_getpid()); | |
255 msg("file name: %s", file); | |
256 playit(); | |
257 /*NOTREACHED*/ | |
258 return(0); | |
259 } | |
260 | |
261 static int encerrno = 0; | |
262 | |
263 int | |
264 encerror() | |
265 { | |
266 return encerrno; | |
267 } | |
268 | |
269 void | |
270 encseterr(int err) | |
271 { | |
272 encerrno = err; | |
273 } | |
274 | |
275 int | |
276 encclearerr() | |
277 { | |
278 int n = encerrno; | |
279 | |
280 encerrno = 0; | |
281 | |
282 return(n); | |
283 } | |
284 | |
285 /* | |
286 * encwrite: | |
287 * Perform an encrypted write | |
288 */ | |
289 | |
290 size_t | |
291 encwrite(const char *start, size_t size, FILE *outf) | |
292 { | |
293 const char *e1, *e2; | |
294 char fb; | |
295 int temp; | |
296 size_t o_size = size; | |
297 e1 = encstr; | |
298 e2 = statlist; | |
299 fb = 0; | |
300 | |
301 if (encerrno) { | |
302 errno = encerrno; | |
303 return 0; | |
304 } | |
305 | |
306 while(size) | |
307 { | |
308 if (putc(*start++ ^ *e1 ^ *e2 ^ fb, outf) == EOF) | |
309 { | |
310 encerrno = errno; | |
311 break; | |
312 } | |
313 | |
314 temp = *e1++; | |
315 fb = fb + ((char) (temp * *e2++)); | |
316 if (*e1 == '\0') | |
317 e1 = encstr; | |
318 if (*e2 == '\0') | |
319 e2 = statlist; | |
320 size--; | |
321 } | |
322 | |
323 return(o_size - size); | |
324 } | |
325 | |
326 /* | |
327 * encread: | |
328 * Perform an encrypted read | |
329 */ | |
330 size_t | |
331 encread(char *start, size_t size, FILE *inf) | |
332 { | |
333 const char *e1, *e2; | |
334 char fb; | |
335 int temp; | |
336 size_t read_size; | |
337 size_t items; | |
338 fb = 0; | |
339 | |
340 if (encerrno) { | |
341 errno = encerrno; | |
342 return 0; | |
343 } | |
344 | |
345 items = read_size = fread(start,1,size,inf); | |
346 | |
347 e1 = encstr; | |
348 e2 = statlist; | |
349 | |
350 while (read_size--) | |
351 { | |
352 *start++ ^= *e1 ^ *e2 ^ fb; | |
353 temp = *e1++; | |
354 fb = fb + (char)(temp * *e2++); | |
355 if (*e1 == '\0') | |
356 e1 = encstr; | |
357 if (*e2 == '\0') | |
358 e2 = statlist; | |
359 } | |
360 | |
361 if (items != size) | |
362 encerrno = errno; | |
363 | |
364 return(items); | |
365 } | |
366 | |
367 /* | |
368 * read_scrore | |
369 * Read in the score file | |
370 */ | |
371 void | |
372 rd_score(SCORE *top_ten) | |
373 { | |
374 char scoreline[100]; | |
375 int i; | |
376 | |
377 if (scoreboard == NULL) | |
378 return; | |
379 | |
380 rewind(scoreboard); | |
381 | |
382 for(i = 0; i < numscores; i++) | |
383 { | |
384 encread(top_ten[i].sc_name, MAXSTR, scoreboard); | |
385 scoreline[0] = '\0'; | |
386 encread(scoreline, 100, scoreboard); | |
387 (void) sscanf(scoreline, " %u %d %u %d %d %x \n", | |
388 &top_ten[i].sc_uid, &top_ten[i].sc_score, | |
389 &top_ten[i].sc_flags, &top_ten[i].sc_monster, | |
390 &top_ten[i].sc_level, &top_ten[i].sc_time); | |
391 } | |
392 | |
393 rewind(scoreboard); | |