Annotation of early-roguelike/arogue7/save.c, Revision 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