Mercurial > hg > early-roguelike
comparison arogue7/save.c @ 125:adfa37e67084
Import Advanced Rogue 7.7 from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Fri, 08 May 2015 15:24:40 -0400 |
parents | |
children | b786053d2f37 |
comparison
equal
deleted
inserted
replaced
124:d10fc4a065ac | 125:adfa37e67084 |
---|---|
1 /* | |
2 * save.c - save and restore routines | |
3 * | |
4 * Advanced Rogue | |
5 * Copyright (C) 1984, 1985, 1986 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 /* | |
16 * save and restore routines | |
17 * | |
18 */ | |
19 | |
20 #include "curses.h" | |
21 #include <ctype.h> | |
22 #include <sys/types.h> | |
23 #include <sys/stat.h> | |
24 #include <signal.h> | |
25 #include "rogue.h" | |
26 #include <fcntl.h> | |
27 #include <errno.h> | |
28 #include "mach_dep.h" | |
29 #ifdef PC7300 | |
30 #include "sys/window.h" | |
31 extern struct uwdata wdata; | |
32 #endif | |
33 | |
34 #if u370 || uts | |
35 #define ENCREAD(b,n,fd) read(fd,b,n) | |
36 #define ENCWRITE(b,n,fd) write(fd,b,n) | |
37 #endif | |
38 #ifndef ENCREAD | |
39 #define ENCREAD encread | |
40 #define ENCWRITE encwrite | |
41 #endif | |
42 | |
43 typedef struct stat STAT; | |
44 | |
45 extern char version[], encstr[]; | |
46 /* extern bool _endwin; */ | |
47 extern int errno; | |
48 | |
49 STAT sbuf; | |
50 | |
51 bool | |
52 save_game() | |
53 { | |
54 register int savefd; | |
55 register int c; | |
56 char buf[LINELEN]; | |
57 | |
58 /* | |
59 * get file name | |
60 */ | |
61 mpos = 0; | |
62 if (file_name[0] != '\0') | |
63 { | |
64 msg("Save file (%s)? ", file_name); | |
65 do | |
66 { | |
67 c = readchar(); | |
68 if (c == ESCAPE) return(0); | |
69 } while (c != 'n' && c != 'N' && c != 'y' && c != 'Y'); | |
70 mpos = 0; | |
71 if (c == 'y' || c == 'Y') | |
72 { | |
73 msg("File name: %s", file_name); | |
74 goto gotfile; | |
75 } | |
76 } | |
77 | |
78 do | |
79 { | |
80 msg("File name: "); | |
81 mpos = 0; | |
82 buf[0] = '\0'; | |
83 if (get_str(buf, msgw) == QUIT) | |
84 { | |
85 msg(""); | |
86 return FALSE; | |
87 } | |
88 strcpy(file_name, buf); | |
89 gotfile: | |
90 if ((savefd = open(file_name, O_WRONLY|O_CREAT|O_TRUNC,0666)) < 0) | |
91 msg(strerror(errno)); /* fake perror() */ | |
92 } while (savefd < 0); | |
93 | |
94 /* | |
95 * write out encrpyted file (after a stat) | |
96 */ | |
97 if (save_file(savefd) == FALSE) { | |
98 msg("Cannot create save file."); | |
99 unlink(file_name); | |
100 return(FALSE); | |
101 } | |
102 else return(TRUE); | |
103 } | |
104 | |
105 /* | |
106 * automatically save a file. This is used if a HUP signal is | |
107 * recieved | |
108 */ | |
109 void | |
110 auto_save(sig) | |
111 int sig; | |
112 { | |
113 register int savefd; | |
114 register int i; | |
115 | |
116 for (i = 0; i < NSIG; i++) | |
117 signal(i, SIG_IGN); | |
118 if (file_name[0] != '\0' && | |
119 pstats.s_hpt > 0 && | |
120 (savefd = open(file_name, O_WRONLY|O_CREAT|O_TRUNC, 0600)) >= 0) | |
121 save_file(savefd); | |
122 endwin(); | |
123 #ifdef PC7300 | |
124 endhardwin(); | |
125 #endif | |
126 exit(1); | |
127 } | |
128 | |
129 /* | |
130 * write the saved game on the file | |
131 */ | |
132 bool | |
133 save_file(savefd) | |
134 register int savefd; | |
135 { | |
136 register unsigned num_to_write, num_written; | |
137 FILE *savef; | |
138 int ret; | |
139 | |
140 wmove(cw, lines-1, 0); | |
141 draw(cw); | |
142 lseek(savefd, 0L, 0); | |
143 fstat(savefd, &sbuf); | |
144 num_to_write = strlen(version) + 1; | |
145 num_written = ENCWRITE(version, num_to_write, savefd); | |
146 sprintf(prbuf,"%d x %d\n", LINES, COLS); | |
147 ENCWRITE(prbuf,80,savefd); | |
148 savef = (FILE *) fdopen(savefd,"wb"); | |
149 ret = rs_save_file(savef); | |
150 fclose(savef); | |
151 if (num_to_write == num_written && ret == 0) return(TRUE); | |
152 else return(FALSE); | |
153 } | |
154 | |
155 restore(file, envp) | |
156 register char *file; | |
157 char **envp; | |
158 { | |
159 register int inf; | |
160 extern char **environ; | |
161 char buf[LINELEN]; | |
162 STAT sbuf2; | |
163 int oldcol, oldline; /* Old number of columns and lines */ | |
164 | |
165 if (strcmp(file, "-r") == 0) | |
166 file = file_name; | |
167 if ((inf = open(file, 0)) < 0) | |
168 { | |
169 perror(file); | |
170 return FALSE; | |
171 } | |
172 | |
173 fflush(stdout); | |
174 ENCREAD(buf, strlen(version) + 1, inf); | |
175 if (strcmp(buf, version) != 0) | |
176 { | |
177 printf("Sorry, saved game is out of date.\n"); | |
178 return FALSE; | |
179 } | |
180 | |
181 /* | |
182 * Get the lines and columns from the previous game | |
183 */ | |
184 | |
185 ENCREAD(buf, 80, inf); | |
186 sscanf(buf, "%d x %d\n", &oldline, &oldcol); | |
187 fstat(inf, &sbuf2); | |
188 fflush(stdout); | |
189 | |
190 initscr(); | |
191 | |
192 if (COLS < oldcol || LINES < oldline) { | |
193 endwin(); | |
194 printf("Cannot restart the game on a smaller screen.\n"); | |
195 return FALSE; | |
196 } | |
197 | |
198 setup(); | |
199 /* | |
200 * Set up windows | |
201 */ | |
202 cw = newwin(lines, cols, 0, 0); | |
203 mw = newwin(lines, cols, 0, 0); | |
204 hw = newwin(lines, cols, 0, 0); | |
205 msgw = newwin(4, cols, 0, 0); | |
206 | |
207 keypad(cw,1); | |
208 keypad(msgw,1); | |
209 | |
210 if (rs_restore_file(inf) != 0) | |
211 { | |
212 printf("Cannot restore file\n"); | |
213 close(inf); | |
214 return(FALSE); | |
215 } | |
216 | |
217 cols = COLS; | |
218 lines = LINES; | |
219 if (cols > 85) cols = 85; | |
220 if (lines > 24) lines = 24; | |
221 | |
222 mpos = 0; | |
223 mvwprintw(msgw, 0, 0, "%s: %s", file, ctime(&sbuf2.st_mtime)); | |
224 | |
225 /* | |
226 * defeat multiple restarting from the same place | |
227 */ | |
228 if (!wizard && md_unlink_open_file(file, inf) < 0) { | |
229 printf("Cannot unlink file\n"); | |
230 return FALSE; | |
231 } | |
232 | |
233 environ = envp; | |
234 strcpy(file_name, file); | |
235 setup(); | |
236 clearok(curscr, TRUE); | |
237 touchwin(cw); | |
238 srand(getpid()); | |
239 playit(); | |
240 /*NOTREACHED*/ | |
241 return(0); | |
242 } | |
243 | |
244 #define ENCWBSIZ 1024 | |
245 /* | |
246 * perform an encrypted write | |
247 */ | |
248 encwrite(start, size, outf) | |
249 register char *start; | |
250 register unsigned size; | |
251 register int outf; | |
252 { | |
253 register char *ep; | |
254 register int i = 0; | |
255 int num_written = 0; | |
256 auto char buf[ENCWBSIZ]; | |
257 | |
258 ep = encstr; | |
259 | |
260 while (size--) | |
261 { | |
262 buf[i++] = *start++ ^ *ep++ ; | |
263 if (*ep == '\0') | |
264 ep = encstr; | |
265 | |
266 if (i == ENCWBSIZ || size == 0) { | |
267 if (write(outf, buf, (unsigned)i) < i) | |
268 return(num_written); | |
269 else { | |
270 num_written += i; | |
271 i = 0; | |
272 } | |
273 } | |
274 } | |
275 return(num_written); | |
276 } | |
277 | |
278 /* | |
279 * perform an encrypted read | |
280 */ | |
281 encread(start, size, inf) | |
282 register char *start; | |
283 register unsigned size; | |
284 register int inf; | |
285 { | |
286 register char *ep; | |
287 register int read_size; | |
288 | |
289 if ((read_size = read(inf, start, size)) == -1 || read_size == 0) | |
290 return read_size; | |
291 | |
292 ep = encstr; | |
293 | |
294 size = read_size; | |
295 while (size--) | |
296 { | |
297 *start++ ^= *ep++; | |
298 if (*ep == '\0') | |
299 ep = encstr; | |
300 } | |
301 return read_size; | |
302 } |