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 }