comparison arogue5/save.c @ 63:0ed67132cf10

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