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 } |