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