Annotation of early-roguelike/xrogue/save.c, Revision 1.1.1.1
1.1 rubenllo 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 <string.h>
22: #include <stdlib.h>
23: #include <sys/types.h>
24: #include <signal.h>
25: #include <fcntl.h>
26: #include <errno.h>
27: #include "rogue.h"
28: #include "mach_dep.h"
29:
30: extern char version[];
31: extern unsigned char encstr[];
32: extern int big_endian;
33:
34: bool rs_write_int(FILE *savef, int c);
35: bool rs_read_int(FILE *inf, int *i);
36: bool rs_save_file(FILE *savef);
37: bool rs_restore_file(FILE *inf);
38:
39: int md_unlink(char *file);
40: bool save_file(FILE *savef);
41:
42: bool
43: save_game(void)
44: {
45: register FILE *savef;
46: register int c;
47: char buf[LINELEN];
48:
49: /*
50: * get file name
51: */
52: mpos = 0;
53: if (file_name[0] != '\0')
54: {
55: if (use_savedir)
56: msg("Save game? ");
57: else
58: msg("Save file (%s)? ", file_name);
59: do
60: {
61: c = wgetch(cw);
62: if (c == ESC) return(0);
63: } while (c != 'n' && c != 'N' && c != 'y' && c != 'Y');
64: mpos = 0;
65: if (c == 'y' || c == 'Y')
66: {
67: msg("File name: %s", file_name);
68: goto gotfile;
69: }
70: }
71: else
72: goto gotfile; /* must save to file restored from */
73:
74: if (use_savedir) {
75: msg("");
76: return FALSE;
77: }
78:
79: do
80: {
81: msg("File name: ");
82: mpos = 0;
83: buf[0] = '\0';
84: if (get_str(buf, msgw) == QUIT)
85: {
86: msg("");
87: return FALSE;
88: }
89: strcpy(file_name, buf);
90: gotfile:
91:
92: if ((savef = fopen(file_name, "wb")) == NULL) {
93: msg(strerror(errno));
94: if (use_savedir)
95: return FALSE;
96: }
97: } while (savef == NULL);
98:
99: msg("");
100: /*
101: * write out encrpyted file
102: */
103: if (save_file(savef) == FALSE) {
104: fclose(savef);
105: msg("Cannot create save file.");
106: md_unlink(file_name);
107: return(FALSE);
108: }
109: fclose(savef);
110: return(TRUE);
111: }
112:
113: /*
114: * automatically save a file. This is used if a HUP signal is recieved
115: */
116:
117: void
118: auto_save(int sig)
119: {
120: register FILE *savef = NULL;
121: register int i;
122: NOOP(sig);
123: for (i = 0; i < NSIG; i++)
124: signal(i, SIG_IGN);
125: if (file_name[0] != '\0' &&
126: pstats.s_hpt > 0 &&
127: ((savef = fopen(file_name, "wb")) != NULL))
128: save_file(savef);
129: fclose(savef);
130: exit_game(EXIT_ENDWIN);
131: }
132:
133: /*
134: * write the saved game on the file
135: */
136:
137: bool
138: save_file(FILE *savef)
139: {
140: int slines = LINES;
141: int scols = COLS;
142: bool ret = FALSE;
143: int endian = 0x01020304;
144: big_endian = ( *((char *)&endian) == 0x01 );
145:
146: wmove(cw, LINES-1, 0);
147: draw(cw);
148:
149: encwrite(version,strlen(version)+1,savef);
150: rs_write_int(savef,slines);
151: rs_write_int(savef,scols);
152:
153: ret = rs_save_file(savef);
154:
155: return(ret);
156: }
157:
158: bool
159: restore(char *file, char *envp[])
160: {
161: FILE *inf;
162: extern char **environ;
163: char buf[LINELEN];
164: int endian = 0x01020304;
165: big_endian = ( *((char *)&endian) == 0x01 );
166:
167: if (strcmp(file, "-r") == 0)
168: file = file_name;
169:
170: if ((inf = fopen(file, "r")) == NULL)
171: {
172: if (use_savedir && errno == ENOENT)
173: {
174: /* No game in progress, so one will be started. */
175: return TRUE;
176: }
177: perror(file);
178: return FALSE;
179: }
180:
181: fflush(stdout);
182:
183: encread(buf, strlen(version) + 1, inf);
184:
185: if (strcmp(buf, version) != 0)
186: {
187: printf("Sorry, saved game is out of date.\n");
188: return FALSE;
189: }
190:
191: fflush(stdout);
192:
193: rs_read_int(inf,&lines);
194: rs_read_int(inf,&cols);
195:
196: initscr();
197:
198: if (lines > LINES)
199: {
200: endwin();
201: printf("Sorry, original game was played on a screen with %d lines.\n",lines);
202: printf("Current screen only has %d lines. Unable to restore game\n",LINES);
203: return(FALSE);
204: }
205: if (cols > COLS)
206: {
207: endwin();
208: printf("Sorry, original game was played on a screen with %d columns.\n",cols);
209: printf("Current screen only has %d columns. Unable to restore game\n",COLS);
210: return(FALSE);
211: }
212:
213: typeahead(-1);
214: setup();
215: cw = newwin(LINES, COLS, 0, 0);
216: mw = newwin(LINES, COLS, 0, 0);
217: hw = newwin(LINES, COLS, 0, 0);
218: msgw = newwin(4, cols, 0, 0);
219:
220: keypad(cw, TRUE);
221: keypad(hw, TRUE);
222:
223: if (rs_restore_file(inf) == FALSE)
224: {
225: endwin();
226: printf("Cannot restore file\n");
227: fclose(inf);
228: return(FALSE);
229: }
230:
231: fclose(inf);
232:
233: if (!wizard)
234: md_unlink(file);
235:
236: mpos = 0;
237: environ = envp;
238: strcpy(file_name, file);
239: clearok(curscr, TRUE);
240: touchwin(cw);
241: wrefresh(cw);
242: msg("Welcome back! --More-- ");
243: wait_for(' ');
244: msg("");
245: playit();
246:
247: /*NOTREACHED*/
248: return FALSE;
249: }
250:
251: #define ENCWBSIZ 1024
252:
253: /*
254: * perform an encrypted write
255: */
256:
257: long
258: encwrite(char *start, unsigned long size, FILE *outf)
259: {
260: register unsigned char *ep;
261: register int i = 0;
262: unsigned long num_written = 0;
263: char buf[ENCWBSIZ];
264: int ret;
265:
266: ep = encstr;
267:
268: while (size--)
269: {
270: buf[i++] = *start++ ^ *ep++;
271: if (*ep == '\0')
272: ep = encstr;
273:
274: if (i == ENCWBSIZ || size == 0)
275: {
276: ret = (unsigned int) fwrite(buf, 1, i, outf);
277: if (ret > 0)
278: num_written += ret;
279:
280: if (ret < i)
281: return(num_written);
282:
283: i = 0;
284: }
285: }
286: return(num_written);
287: }
288:
289: #define ENCRBSIZ 32768
290:
291: /*
292: * perform an encrypted read
293: */
294:
295: long
296: encread(char *start, unsigned long size, FILE *inf)
297: {
298: register unsigned char *ep;
299: register int rd_siz;
300: register unsigned long total_read;
301:
302: total_read = 0;
303: while (total_read < size) {
304: rd_siz = ENCRBSIZ;
305: rd_siz = ((size-total_read) > ENCRBSIZ) ? ENCRBSIZ : (size-total_read);
306: rd_siz = fread(&start[total_read], 1, rd_siz, inf);
307: if(rd_siz==0)
308: break;
309: total_read += rd_siz;
310: }
311: ep = encstr;
312:
313: size = total_read;
314: while (size--)
315: {
316: *start++ ^= *ep++;
317: if (*ep == '\0')
318: ep = encstr;
319: }
320: return total_read;
321: }
322:
CVSweb