Mercurial > hg > early-roguelike
diff rogue3/save.c @ 0:527e2150eaf0
Import Rogue 3.6 from the Roguelike Restoration Project (r1490)
author | edwarj4 |
---|---|
date | Tue, 13 Oct 2009 13:33:34 +0000 |
parents | |
children | b4856d4d4c4e |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rogue3/save.c Tue Oct 13 13:33:34 2009 +0000 @@ -0,0 +1,297 @@ +/* + * save and restore routines + * + * @(#)save.c 3.9 (Berkeley) 6/16/81 + * + * Rogue: Exploring the Dungeons of Doom + * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman + * All rights reserved. + * + * See the file LICENSE.TXT for full copyright and licensing information. + */ + +#include "curses.h" +#include <ctype.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <signal.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include "machdep.h" +#include "rogue.h" + +typedef struct stat STAT; + +extern char version[], encstr[]; + +STAT sbuf; + +int +save_game() +{ + FILE *savef; + int c; + char buf[80]; + + /* + * get file name + */ + mpos = 0; + if (file_name[0] != '\0') + { + msg("Save file (%s)? ", file_name); + do + { + c = readchar(cw); + } while (c != 'n' && c != 'N' && c != 'y' && c != 'Y'); + mpos = 0; + if (c == 'y' || c == 'Y') + { + msg("File name: %s", file_name); + goto gotfile; + } + } + + do + { + msg("File name: "); + mpos = 0; + buf[0] = '\0'; + if (get_str(buf, cw) == QUIT) + { + msg(""); + return FALSE; + } + strcpy(file_name, buf); +gotfile: + if ((savef = fopen(file_name, "w")) == NULL) + msg(strerror(errno)); /* fake perror() */ + } while (savef == NULL); + + /* + * write out encrpyted file (after a stat) + * The fwrite is to force allocation of the buffer before the write + */ + if (save_file(savef) != 0) + { + msg("Save game failed!"); + return FALSE; + } + return TRUE; +} + +/* + * automatically save a file. This is used if a HUP signal is + * recieved + */ +void +auto_save(int p) +{ + FILE *savef; + int i; + + for (i = 0; i < NSIG; i++) + signal(i, SIG_IGN); + if (file_name[0] != '\0' && (savef = fopen(file_name, "w")) != NULL) + save_file(savef); + endwin(); + exit(1); +} + +/* + * write the saved game on the file + */ +int +save_file(FILE *savef) +{ + char buf[80]; + int ret; + + wmove(cw, LINES-1, 0); + draw(cw); + (void) fseek(savef, 0L, 0); + + memset(buf,0,80); + strcpy(buf,version); + encwrite(buf,80,savef); + memset(buf,0,80); + strcpy(buf,"R36 2\n"); + encwrite(buf,80,savef); + memset(buf,0,80); + sprintf(buf,"%d x %d\n", LINES, COLS); + encwrite(buf,80,savef); + + ret = rs_save_file(savef); + + fclose(savef); + + return(ret); +} + +int +restore(char *file, char **envp) +{ + FILE *inf; + extern char **environ; + char buf[80]; + int slines, scols; + int rogue_version = 0, savefile_version = 0; + + if (strcmp(file, "-r") == 0) + file = file_name; + + if ((inf = fopen(file, "r")) == NULL) + { + perror(file); + return FALSE; + } + + fflush(stdout); + encread(buf, 80, inf); + + if (strcmp(buf, version) != 0) + { + printf("Sorry, saved game is out of date.\n"); + return FALSE; + } + + encread(buf, 80, inf); + (void) sscanf(buf, "R%d %d\n", &rogue_version, &savefile_version); + + if ((rogue_version != 36) && (savefile_version != 2)) + { + printf("Sorry, saved game format is out of date.\n"); + return FALSE; + } + + encread(buf,80,inf); + (void) sscanf(buf,"%d x %d\n",&slines, &scols); + + /* + * we do not close the file so that we will have a hold of the + * inode for as long as possible + */ + + initscr(); + + if (slines > LINES) + { + endwin(); + printf("Sorry, original game was played on a screen with %d lines.\n",slines); + printf("Current screen only has %d lines. Unable to restore game\n",LINES); + return(FALSE); + } + + if (scols > COLS) + { + endwin(); + printf("Sorry, original game was played on a screen with %d columns.\n",scols); + printf("Current screen only has %d columns. Unable to restore game\n",COLS); + return(FALSE); + } + + cw = newwin(LINES, COLS, 0, 0); + mw = newwin(LINES, COLS, 0, 0); + hw = newwin(LINES, COLS, 0, 0); + nocrmode(); + keypad(cw,1); + mpos = 0; + mvwprintw(cw, 0, 0, "%s", file); + + if (rs_restore_file(inf) != 0) + { + endwin(); + printf("Cannot restore file\n"); + return(FALSE); + } + + if (!wizard && (md_unlink_open_file(file, inf) < 0)) + { + endwin(); + printf("Cannot unlink file\n"); + return FALSE; + } + + environ = envp; + strcpy(file_name, file); + setup(); + clearok(curscr, TRUE); + touchwin(cw); + srand(md_getpid()); + status(); + playit(); + /*NOTREACHED*/ + return(0); +} + +static int encerrno = 0; + +int +encerror() +{ + return encerrno; +} + +void +encseterr(int err) +{ + encerrno = err; +} + +int +encclearerr() +{ + int n = encerrno; + + encerrno = 0; + + return(n); +} + +/* + * perform an encrypted write + */ +size_t +encwrite(const void *buf, size_t size, FILE *outf) +{ + char *ep; + const char *start = buf; + size_t o_size = size; + ep = encstr; + + while (size) + { + if (putc(*start++ ^ *ep++, outf) == EOF) + return(o_size - size); + if (*ep == '\0') + ep = encstr; + size--; + } + + return(o_size - size); +} + +/* + * perform an encrypted read + */ +size_t +encread(void *buf, size_t size, FILE *inf) +{ + char *ep; + size_t read_size; + char *start = buf; + + if ((read_size = fread(start,1,size,inf)) == 0) + return 0; + + ep = encstr; + + while (size--) + { + *start++ ^= *ep++; + if (*ep == '\0') + ep = encstr; + } + return read_size; +}