Annotation of early-roguelike/arogue7/save.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: * save.c - save and restore routines
3: *
4: * Advanced Rogue
5: * Copyright (C) 1984, 1985, 1986 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: /*
16: * save and restore routines
17: *
18: */
19:
20: #include "curses.h"
21: #include <ctype.h>
22: #include <stdlib.h>
23: #include <string.h>
24: #include <sys/types.h>
25: #include <sys/stat.h>
26: #include <signal.h>
27: #include <time.h>
28: #include "rogue.h"
29: #include <fcntl.h>
30: #include <errno.h>
31: #include "mach_dep.h"
32: #ifdef PC7300
33: #include "sys/window.h"
34: extern struct uwdata wdata;
35: #endif
36:
37: #if u370 || uts
38: #define ENCREAD(b,n,f) read(md_fileno(f),b,n)
39: #define ENCWRITE(b,n,f) write(md_fileno(f),b,n)
40: #endif
41: #ifndef ENCREAD
42: #define ENCREAD encread
43: #define ENCWRITE encwrite
44: #endif
45:
46: bool save_file(FILE *savef);
47:
48: typedef struct stat STAT;
49:
50: extern char version[], encstr[];
51: /* extern bool _endwin; */
52: extern int errno;
53:
54: STAT sbuf;
55:
56: bool
57: save_game(void)
58: {
59: FILE *savefi = NULL;
60: register int c;
61: char buf[LINELEN];
62:
63: /*
64: * get file name
65: */
66: mpos = 0;
67: if (file_name[0] != '\0')
68: {
69: if (use_savedir)
70: msg("Save game? ");
71: else
72: msg("Save file (%s)? ", file_name);
73: do
74: {
75: c = readchar();
76: if (c == ESCAPE) return(0);
77: } while (c != 'n' && c != 'N' && c != 'y' && c != 'Y');
78: mpos = 0;
79: if (c == 'y' || c == 'Y')
80: {
81: msg("File name: %s", file_name);
82: goto gotfile;
83: }
84: }
85:
86: if (use_savedir)
87: {
88: msg("");
89: return FALSE;
90: }
91:
92: do
93: {
94: msg("File name: ");
95: mpos = 0;
96: buf[0] = '\0';
97: if (get_str(buf, msgw) == QUIT)
98: {
99: msg("");
100: return FALSE;
101: }
102: strcpy(file_name, buf);
103: gotfile:
104: if ((savefi = fopen(file_name, "w")) == NULL)
105: {
106: msg(strerror(errno)); /* fake perror() */
107: if (use_savedir)
108: return FALSE;
109: }
110: } while (savefi == NULL);
111:
112: /*
113: * write out encrpyted file (after a stat)
114: */
115: if (save_file(savefi) == FALSE) {
116: msg("Cannot create save file.");
117: md_unlink(file_name);
118: return(FALSE);
119: }
120: else return(TRUE);
121: }
122:
123: /*
124: * automatically save a file. This is used if a HUP signal is
125: * recieved
126: */
127: void
128: auto_save(int sig)
129: {
130: FILE *savefi;
131: register int i;
132:
133: for (i = 0; i < NSIG; i++)
134: signal(i, SIG_IGN);
135: if (file_name[0] != '\0' &&
136: pstats.s_hpt > 0 &&
137: (savefi = fopen(file_name, "w")) != NULL)
138: save_file(savefi);
139: endwin();
140: #ifdef PC7300
141: endhardwin();
142: #endif
143: exit(1);
144: }
145:
146: /*
147: * write the saved game on the file
148: */
149: bool
150: save_file(FILE *savef)
151: {
152: register unsigned num_to_write, num_written;
153: int ret;
154:
155: wmove(cw, lines-1, 0);
156: draw(cw);
157: fseek(savef, 0L, SEEK_SET);
158: stat(file_name, &sbuf);
159: num_to_write = strlen(version) + 1;
160: num_written = ENCWRITE(version, num_to_write, savef);
161: sprintf(prbuf,"%d x %d\n", LINES, COLS);
162: ENCWRITE(prbuf,80,savef);
163: ret = rs_save_file(savef);
164: fclose(savef);
165: if (num_to_write == num_written && ret == 0) return(TRUE);
166: else return(FALSE);
167: }
168:
169: bool
170: restore(char *file, char *envp[])
171: {
172: FILE *inf;
173: extern char **environ;
174: char buf[LINELEN];
175: STAT sbuf2;
176: int oldcol, oldline; /* Old number of columns and lines */
177:
178: if (strcmp(file, "-r") == 0)
179: file = file_name;
180: if ((inf = fopen(file, "r")) == NULL)
181: {
182: if (use_savedir && errno == ENOENT)
183: {
184: return TRUE;
185: }
186: perror(file);
187: return FALSE;
188: }
189:
190: fflush(stdout);
191: ENCREAD(buf, strlen(version) + 1, inf);
192: if (strcmp(buf, version) != 0)
193: {
194: printf("Sorry, saved game is out of date.\n");
195: return FALSE;
196: }
197:
198: /*
199: * Get the lines and columns from the previous game
200: */
201:
202: ENCREAD(buf, 80, inf);
203: sscanf(buf, "%d x %d\n", &oldline, &oldcol);
204: stat(file, &sbuf2);
205: fflush(stdout);
206:
207: initscr();
208:
209: if (COLS < oldcol || LINES < oldline) {
210: endwin();
211: printf("Cannot restart the game on a smaller screen.\n");
212: return FALSE;
213: }
214:
215: setup();
216: /*
217: * Set up windows
218: */
219: cw = newwin(lines, cols, 0, 0);
220: mw = newwin(lines, cols, 0, 0);
221: hw = newwin(lines, cols, 0, 0);
222: msgw = newwin(4, cols, 0, 0);
223:
224: keypad(cw,1);
225: keypad(msgw,1);
226:
227: if (rs_restore_file(inf) != 0)
228: {
229: printf("Cannot restore file\n");
230: fclose(inf);
231: return(FALSE);
232: }
233:
234: cols = COLS;
235: lines = LINES;
236: if (cols > 85) cols = 85;
237: if (lines > 24) lines = 24;
238:
239: mpos = 0;
240: msg("");
241: msg("%s: %s", file, ctime(&sbuf2.st_mtime));
242:
243: /*
244: * defeat multiple restarting from the same place
245: */
246: if (!wizard && md_unlink_open_file(file, inf) < 0) {
247: printf("Cannot unlink file\n");
248: return FALSE;
249: }
250:
251: environ = envp;
252: strcpy(file_name, file);
253: setup();
254: clearok(curscr, TRUE);
255: touchwin(cw);
256: srand(md_random_seed());
257: playit();
258: /*NOTREACHED*/
259: return(0);
260: }
261:
262: #define ENCWBSIZ 1024
263: /*
264: * perform an encrypted write
265: */
266: int
267: encwrite(char *start, unsigned int size, FILE *outf)
268: {
269: register char *ep;
270: register int i = 0;
271: int num_written = 0;
272: auto char buf[ENCWBSIZ];
273:
274: ep = encstr;
275:
276: while (size--)
277: {
278: buf[i++] = *start++ ^ *ep++ ;
279: if (*ep == '\0')
280: ep = encstr;
281:
282: if (i == ENCWBSIZ || size == 0) {
283: if (fwrite(buf, 1, (unsigned)i, outf) < i)
284: return(num_written);
285: else {
286: num_written += i;
287: i = 0;
288: }
289: }
290: }
291: return(num_written);
292: }
293:
294: /*
295: * perform an encrypted read
296: */
297: int
298: encread(char *start, unsigned int size, FILE *inf)
299: {
300: register char *ep;
301: register int read_size;
302:
303: if ((read_size = fread(start, 1, size, inf)) == 0)
304: return read_size;
305:
306: ep = encstr;
307:
308: size = read_size;
309: while (size--)
310: {
311: *start++ ^= *ep++;
312: if (*ep == '\0')
313: ep = encstr;
314: }
315: return read_size;
316: }
CVSweb