Annotation of early-roguelike/rogue3/save.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: * save and restore routines
3: *
4: * @(#)save.c 3.9 (Berkeley) 6/16/81
5: *
6: * Rogue: Exploring the Dungeons of Doom
7: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
8: * All rights reserved.
9: *
10: * See the file LICENSE.TXT for full copyright and licensing information.
11: */
12:
13: #include "curses.h"
14: #include <ctype.h>
15: #include <sys/types.h>
16: #include <sys/stat.h>
17: #include <signal.h>
18: #include <errno.h>
19: #include <string.h>
20: #include <stdlib.h>
21: #include "machdep.h"
22: #include "rogue.h"
23:
24: typedef struct stat STAT;
25:
26: extern char version[], encstr[];
27:
28: STAT sbuf;
29:
30: int
31: save_game()
32: {
33: FILE *savef;
34: int c;
35: char buf[80];
36:
37: /*
38: * get file name
39: */
40: mpos = 0;
41: if (file_name[0] != '\0')
42: {
43: if (use_savedir)
44: msg("Save game? ");
45: else
46: msg("Save file (%s)? ", file_name);
47: do
48: {
49: c = readchar(cw);
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: if (use_savedir)
58: return FALSE;
59: /* because you're not allowed to change the savefile if
60: you're using the system savedir! */
61: }
62:
63: do
64: {
65: msg("File name: ");
66: mpos = 0;
67: buf[0] = '\0';
68: if (get_str(buf, cw) == QUIT)
69: {
70: msg("");
71: return FALSE;
72: }
73: strcpy(file_name, buf);
74: gotfile:
75: if ((savef = fopen(file_name, "w")) == NULL)
76: {
77: msg(strerror(errno)); /* fake perror() */
78: if (use_savedir)
79: return FALSE;
80: }
81: } while (savef == NULL);
82:
83: /*
84: * write out encrypted file (after a stat)
85: * The fwrite is to force allocation of the buffer before the write
86: */
87: if (save_file(savef) != 0)
88: {
89: msg("Save game failed!");
90: return FALSE;
91: }
92: return TRUE;
93: }
94:
95: /*
96: * automatically save a file. This is used if a HUP signal is
97: * recieved
98: */
99: void
100: auto_save(int p)
101: {
102: FILE *savef;
103: int i;
104:
105: for (i = 0; i < NSIG; i++)
106: signal(i, SIG_IGN);
107: if (file_name[0] != '\0' && (savef = fopen(file_name, "w")) != NULL)
108: save_file(savef);
109: endwin();
110: exit(1);
111: }
112:
113: /*
114: * write the saved game on the file
115: */
116: int
117: save_file(FILE *savef)
118: {
119: char buf[80];
120: int ret;
121:
122: wmove(cw, LINES-1, 0);
123: draw(cw);
124: (void) fseek(savef, 0L, 0);
125:
126: memset(buf,0,80);
127: strcpy(buf,version);
128: encwrite(buf,80,savef);
129: memset(buf,0,80);
130: strcpy(buf,"R36 2\n");
131: encwrite(buf,80,savef);
132: memset(buf,0,80);
133: sprintf(buf,"%d x %d\n", LINES, COLS);
134: encwrite(buf,80,savef);
135:
136: ret = rs_save_file(savef);
137:
138: fclose(savef);
139:
140: return(ret);
141: }
142:
143: int
144: restore(char *file, char **envp)
145: {
146: FILE *inf;
147: extern char **environ;
148: char buf[80];
149: int slines, scols;
150: int rogue_version = 0, savefile_version = 0;
151:
152: if (strcmp(file, "-r") == 0)
153: file = file_name;
154:
155: if ((inf = fopen(file, "r")) == NULL)
156: {
157: if (use_savedir && errno == ENOENT)
158: {
159: /* We're using the system savefile and it doesn't exist.
160: * This isn't a fatal error, we'll just start a new game. */
161: return TRUE;
162: }
163: else
164: {
165: perror(file);
166: return FALSE;
167: }
168: }
169:
170: fflush(stdout);
171: encread(buf, 80, inf);
172:
173: if (strcmp(buf, version) != 0)
174: {
175: printf("Sorry, saved game is out of date.\n");
176: return FALSE;
177: }
178:
179: encread(buf, 80, inf);
180: (void) sscanf(buf, "R%d %d\n", &rogue_version, &savefile_version);
181:
182: if ((rogue_version != 36) && (savefile_version != 2))
183: {
184: printf("Sorry, saved game format is out of date.\n");
185: return FALSE;
186: }
187:
188: encread(buf,80,inf);
189: (void) sscanf(buf,"%d x %d\n",&slines, &scols);
190:
191: /*
192: * we do not close the file so that we will have a hold of the
193: * inode for as long as possible
194: */
195:
196: initscr();
197:
198: if (slines > LINES)
199: {
200: endwin();
201: printf("Sorry, original game was played on a screen with %d lines.\n",slines);
202: printf("Current screen only has %d lines. Unable to restore game\n",LINES);
203: return(FALSE);
204: }
205:
206: if (scols > COLS)
207: {
208: endwin();
209: printf("Sorry, original game was played on a screen with %d columns.\n",scols);
210: printf("Current screen only has %d columns. Unable to restore game\n",COLS);
211: return(FALSE);
212: }
213:
214: cw = newwin(LINES, COLS, 0, 0);
215: mw = newwin(LINES, COLS, 0, 0);
216: hw = newwin(LINES, COLS, 0, 0);
217: nonl();
218: nocrmode();
219: keypad(cw,1);
220: mpos = 0;
221: mvwprintw(cw, 0, 0, "%s", file);
222:
223: if (rs_restore_file(inf) != 0)
224: {
225: endwin();
226: printf("Cannot restore file\n");
227: return(FALSE);
228: }
229:
230: if (!wizard && (md_unlink_open_file(file, inf) < 0))
231: {
232: endwin();
233: printf("Cannot unlink file\n");
234: return FALSE;
235: }
236:
237: if (pstats.s_hpt <= 0) {
238: endwin();
239: printf("This character is already dead.\n");
240: return FALSE;
241: }
242:
243: environ = envp;
244: strcpy(file_name, file);
245: setup();
246: clearok(curscr, TRUE);
247: touchwin(cw);
248: srand(md_random_seed());
249: status();
250: playit();
251: /*NOTREACHED*/
252: return(0);
253: }
254:
255: static int encerrno = 0;
256:
257: int
258: encerror()
259: {
260: return encerrno;
261: }
262:
263: void
264: encseterr(int err)
265: {
266: encerrno = err;
267: }
268:
269: int
270: encclearerr()
271: {
272: int n = encerrno;
273:
274: encerrno = 0;
275:
276: return(n);
277: }
278:
279: /*
280: * perform an encrypted write
281: */
282: size_t
283: encwrite(const void *buf, size_t size, FILE *outf)
284: {
285: char *ep;
286: const char *start = buf;
287: size_t o_size = size;
288: ep = encstr;
289:
290: while (size)
291: {
292: if (putc(*start++ ^ *ep++, outf) == EOF)
293: return(o_size - size);
294: if (*ep == '\0')
295: ep = encstr;
296: size--;
297: }
298:
299: return(o_size - size);
300: }
301:
302: /*
303: * perform an encrypted read
304: */
305: size_t
306: encread(void *buf, size_t size, FILE *inf)
307: {
308: char *ep;
309: size_t read_size;
310: char *start = buf;
311:
312: if ((read_size = fread(start,1,size,inf)) == 0)
313: return 0;
314:
315: ep = encstr;
316:
317: while (size--)
318: {
319: *start++ ^= *ep++;
320: if (*ep == '\0')
321: ep = encstr;
322: }
323: return read_size;
324: }
CVSweb