comparison xrogue/save.c @ 133:e6179860cb76

Import XRogue 8.0 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 21 Apr 2015 08:55:20 -0400
parents
children ce0cf824c192
comparison
equal deleted inserted replaced
124:d10fc4a065ac 133:e6179860cb76
1 /*
2 save.c - save and restore routines
3
4 XRogue: Expeditions into the Dungeons of Doom
5 Copyright (C) 1991 Robert Pietkivitch
6 All rights reserved.
7
8 Based on "Advanced Rogue"
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
10 All rights reserved.
11
12 Based on "Rogue: Exploring the Dungeons of Doom"
13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
14 All rights reserved.
15
16 See the file LICENSE.TXT for full copyright and licensing information.
17 */
18
19 #include <curses.h>
20 #include <ctype.h>
21 #include <sys/types.h>
22 #include <signal.h>
23 #include <fcntl.h>
24 #include <errno.h>
25 #include "rogue.h"
26 #include "mach_dep.h"
27
28 extern char version[];
29 extern unsigned char encstr[];
30 extern int big_endian;
31
32 bool
33 save_game()
34 {
35 register FILE *savef;
36 register int c;
37 char buf[LINELEN];
38
39 /*
40 * get file name
41 */
42 mpos = 0;
43 if (file_name[0] != '\0')
44 {
45 msg("Save file (%s)? ", file_name);
46 do
47 {
48 c = wgetch(cw);
49 if (c == ESC) return(0);
50 } while (c != 'n' && c != 'N' && c != 'y' && c != 'Y');
51 mpos = 0;
52 if (c == 'y' || c == 'Y')
53 {
54 msg("File name: %s", file_name);
55 goto gotfile;
56 }
57 }
58 else
59 goto gotfile; /* must save to file restored from */
60
61 do
62 {
63 msg("File name: ");
64 mpos = 0;
65 buf[0] = '\0';
66 if (get_str(buf, msgw) == QUIT)
67 {
68 msg("");
69 return FALSE;
70 }
71 strcpy(file_name, buf);
72 gotfile:
73
74 if ((savef = fopen(file_name, "wb")) == NULL)
75 msg(strerror(errno));
76 } while (savef == NULL);
77
78 msg("");
79 /*
80 * write out encrpyted file
81 */
82 if (save_file(savef) == FALSE) {
83 fclose(savef);
84 msg("Cannot create save file.");
85 unlink(file_name);
86 return(FALSE);
87 }
88 fclose(savef);
89 return(TRUE);
90 }
91
92 /*
93 * automatically save a file. This is used if a HUP signal is recieved
94 */
95
96 void
97 auto_save(int sig)
98 {
99 register FILE *savef = NULL;
100 register int i;
101 NOOP(sig);
102 for (i = 0; i < NSIG; i++)
103 signal(i, SIG_IGN);
104 if (file_name[0] != '\0' &&
105 pstats.s_hpt > 0 &&
106 ((savef = fopen(file_name, "wb")) != NULL))
107 save_file(savef);
108 fclose(savef);
109 exit_game(EXIT_ENDWIN);
110 }
111
112 /*
113 * write the saved game on the file
114 */
115
116 bool
117 save_file(savef)
118 register FILE *savef;
119 {
120 int slines = LINES;
121 int scols = COLS;
122 int ret = FALSE;
123 int endian = 0x01020304;
124 big_endian = ( *((char *)&endian) == 0x01 );
125
126 wmove(cw, LINES-1, 0);
127 draw(cw);
128
129 encwrite(version,strlen(version)+1,savef);
130 rs_write_int(savef,slines);
131 rs_write_int(savef,scols);
132
133 ret = rs_save_file(savef);
134
135 return(ret);
136 }
137
138 restore(file, envp)
139 register char *file;
140 char **envp;
141 {
142 register int inf;
143 extern char **environ;
144 char buf[LINELEN];
145 int endian = 0x01020304;
146 big_endian = ( *((char *)&endian) == 0x01 );
147
148 if (strcmp(file, "-r") == 0)
149 file = file_name;
150
151 if ((inf = open(file, O_RDONLY)) < 0)
152 {
153 perror(file);
154 return(-1);
155 }
156
157 fflush(stdout);
158
159 encread(buf, strlen(version) + 1, inf);
160
161 if (strcmp(buf, version) != 0)
162 {
163 printf("Sorry, saved game is out of date.\n");
164 return FALSE;
165 }
166
167 fflush(stdout);
168
169 rs_read_int(inf,&lines);
170 rs_read_int(inf,&cols);
171
172 initscr();
173
174 if (lines > LINES)
175 {
176 endwin();
177 printf("Sorry, original game was played on a screen with %d lines.\n",lines);
178 printf("Current screen only has %d lines. Unable to restore game\n",LINES);
179 return(FALSE);
180 }
181 if (cols > COLS)
182 {
183 endwin();
184 printf("Sorry, original game was played on a screen with %d columns.\n",cols);
185 printf("Current screen only has %d columns. Unable to restore game\n",COLS);
186 return(FALSE);
187 }
188
189 typeahead(-1);
190 setup();
191 cw = newwin(LINES, COLS, 0, 0);
192 mw = newwin(LINES, COLS, 0, 0);
193 hw = newwin(LINES, COLS, 0, 0);
194 msgw = newwin(4, cols, 0, 0);
195
196 keypad(cw, TRUE);
197 keypad(hw, TRUE);
198
199 if (rs_restore_file(inf) == FALSE)
200 {
201 endwin();
202 printf("Cannot restore file\n");
203 close(inf);
204 return(FALSE);
205 }
206
207 close(inf);
208
209 if (!wizard)
210 unlink(file);
211
212 mpos = 0;
213 environ = envp;
214 strcpy(file_name, file);
215 clearok(curscr, TRUE);
216 touchwin(cw);
217 wrefresh(cw);
218 msg("Welcome back! --More-- ");
219 wait_for(' ');
220 msg("");
221 playit();
222
223 /*NOTREACHED*/
224 return(1);
225 }
226
227 #define ENCWBSIZ 1024
228
229 /*
230 * perform an encrypted write
231 */
232
233 long
234 encwrite(start, size, outf)
235 register char *start;
236 register unsigned long size;
237 register FILE *outf;
238 {
239 register unsigned char *ep;
240 register int i = 0;
241 unsigned long num_written = 0;
242 char buf[ENCWBSIZ];
243 int ret;
244
245 ep = encstr;
246
247 while (size--)
248 {
249 buf[i++] = *start++ ^ *ep++;
250 if (*ep == '\0')
251 ep = encstr;
252
253 if (i == ENCWBSIZ || size == 0)
254 {
255 ret = (unsigned int) fwrite(buf, 1, i, outf);
256 if (ret > 0)
257 num_written += ret;
258
259 if (ret < i)
260 return(num_written);
261
262 i = 0;
263 }
264 }
265 return(num_written);
266 }
267
268 #define ENCRBSIZ 32768
269
270 /*
271 * perform an encrypted read
272 */
273
274 long
275 encread(start, size, inf)
276 register char *start;
277 register unsigned long size;
278 int inf;
279 {
280 register unsigned char *ep;
281 register int rd_siz;
282 register unsigned long total_read;
283
284 total_read = 0;
285 while (total_read < size) {
286 rd_siz = ENCRBSIZ;
287 rd_siz = ((size-total_read) > ENCRBSIZ) ? ENCRBSIZ : (size-total_read);
288 rd_siz = read(inf,&start[total_read],rd_siz);
289 if(rd_siz==-1 || rd_siz==0)
290 break;
291 total_read += rd_siz;
292 }
293 ep = encstr;
294
295 size = total_read;
296 while (size--)
297 {
298 *start++ ^= *ep++;
299 if (*ep == '\0')
300 ep = encstr;
301 }
302 return total_read;
303 }
304