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