Mercurial > hg > early-roguelike
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 |