Mercurial > hg > early-roguelike
comparison xrogue/save.c @ 133:e6179860cb76
Import XRogue 8.0 from the Roguelike Restoration Project (r1490)
| author | John "Elwin" Edwards |
|---|---|
| date | Tue, 21 Apr 2015 08:55:20 -0400 |
| parents | |
| children | ce0cf824c192 |
comparison
equal
deleted
inserted
replaced
| 124:d10fc4a065ac | 133:e6179860cb76 |
|---|---|
| 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 <sys/types.h> | |
| 22 #include <signal.h> | |
| 23 #include <fcntl.h> | |
| 24 #include <errno.h> | |
| 25 #include "rogue.h" | |
| 26 #include "mach_dep.h" | |
| 27 | |
| 28 extern char version[]; | |
| 29 extern unsigned char encstr[]; | |
| 30 extern int big_endian; | |
| 31 | |
| 32 bool | |
| 33 save_game() | |
| 34 { | |
| 35 register FILE *savef; | |
| 36 register int c; | |
| 37 char buf[LINELEN]; | |
| 38 | |
| 39 /* | |
| 40 * get file name | |
| 41 */ | |
| 42 mpos = 0; | |
| 43 if (file_name[0] != '\0') | |
| 44 { | |
| 45 msg("Save file (%s)? ", file_name); | |
| 46 do | |
| 47 { | |
| 48 c = wgetch(cw); | |
| 49 if (c == ESC) return(0); | |
| 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 } | |
| 58 else | |
| 59 goto gotfile; /* must save to file restored from */ | |
| 60 | |
| 61 do | |
| 62 { | |
| 63 msg("File name: "); | |
| 64 mpos = 0; | |
| 65 buf[0] = '\0'; | |
| 66 if (get_str(buf, msgw) == QUIT) | |
| 67 { | |
| 68 msg(""); | |
| 69 return FALSE; | |
| 70 } | |
| 71 strcpy(file_name, buf); | |
| 72 gotfile: | |
| 73 | |
| 74 if ((savef = fopen(file_name, "wb")) == NULL) | |
| 75 msg(strerror(errno)); | |
| 76 } while (savef == NULL); | |
| 77 | |
| 78 msg(""); | |
| 79 /* | |
| 80 * write out encrpyted file | |
| 81 */ | |
| 82 if (save_file(savef) == FALSE) { | |
| 83 fclose(savef); | |
| 84 msg("Cannot create save file."); | |
| 85 unlink(file_name); | |
| 86 return(FALSE); | |
| 87 } | |
| 88 fclose(savef); | |
| 89 return(TRUE); | |
| 90 } | |
| 91 | |
| 92 /* | |
| 93 * automatically save a file. This is used if a HUP signal is recieved | |
| 94 */ | |
| 95 | |
| 96 void | |
| 97 auto_save(int sig) | |
| 98 { | |
| 99 register FILE *savef = NULL; | |
| 100 register int i; | |
| 101 NOOP(sig); | |
| 102 for (i = 0; i < NSIG; i++) | |
| 103 signal(i, SIG_IGN); | |
| 104 if (file_name[0] != '\0' && | |
| 105 pstats.s_hpt > 0 && | |
| 106 ((savef = fopen(file_name, "wb")) != NULL)) | |
| 107 save_file(savef); | |
| 108 fclose(savef); | |
| 109 exit_game(EXIT_ENDWIN); | |
| 110 } | |
| 111 | |
| 112 /* | |
| 113 * write the saved game on the file | |
| 114 */ | |
| 115 | |
| 116 bool | |
| 117 save_file(savef) | |
| 118 register FILE *savef; | |
| 119 { | |
| 120 int slines = LINES; | |
| 121 int scols = COLS; | |
| 122 int ret = FALSE; | |
| 123 int endian = 0x01020304; | |
| 124 big_endian = ( *((char *)&endian) == 0x01 ); | |
| 125 | |
| 126 wmove(cw, LINES-1, 0); | |
| 127 draw(cw); | |
| 128 | |
| 129 encwrite(version,strlen(version)+1,savef); | |
| 130 rs_write_int(savef,slines); | |
| 131 rs_write_int(savef,scols); | |
| 132 | |
| 133 ret = rs_save_file(savef); | |
| 134 | |
| 135 return(ret); | |
| 136 } | |
| 137 | |
| 138 restore(file, envp) | |
| 139 register char *file; | |
| 140 char **envp; | |
| 141 { | |
| 142 register int inf; | |
| 143 extern char **environ; | |
| 144 char buf[LINELEN]; | |
| 145 int endian = 0x01020304; | |
| 146 big_endian = ( *((char *)&endian) == 0x01 ); | |
| 147 | |
| 148 if (strcmp(file, "-r") == 0) | |
| 149 file = file_name; | |
| 150 | |
| 151 if ((inf = open(file, O_RDONLY)) < 0) | |
| 152 { | |
| 153 perror(file); | |
| 154 return(-1); | |
| 155 } | |
| 156 | |
| 157 fflush(stdout); | |
| 158 | |
| 159 encread(buf, strlen(version) + 1, inf); | |
| 160 | |
| 161 if (strcmp(buf, version) != 0) | |
| 162 { | |
| 163 printf("Sorry, saved game is out of date.\n"); | |
| 164 return FALSE; | |
| 165 } | |
| 166 | |
| 167 fflush(stdout); | |
| 168 | |
| 169 rs_read_int(inf,&lines); | |
| 170 rs_read_int(inf,&cols); | |
| 171 | |
| 172 initscr(); | |
| 173 | |
| 174 if (lines > LINES) | |
| 175 { | |
| 176 endwin(); | |
| 177 printf("Sorry, original game was played on a screen with %d lines.\n",lines); | |
| 178 printf("Current screen only has %d lines. Unable to restore game\n",LINES); | |
| 179 return(FALSE); | |
| 180 } | |
| 181 if (cols > COLS) | |
| 182 { | |
| 183 endwin(); | |
| 184 printf("Sorry, original game was played on a screen with %d columns.\n",cols); | |
| 185 printf("Current screen only has %d columns. Unable to restore game\n",COLS); | |
| 186 return(FALSE); | |
| 187 } | |
| 188 | |
| 189 typeahead(-1); | |
| 190 setup(); | |
| 191 cw = newwin(LINES, COLS, 0, 0); | |
| 192 mw = newwin(LINES, COLS, 0, 0); | |
| 193 hw = newwin(LINES, COLS, 0, 0); | |
| 194 msgw = newwin(4, cols, 0, 0); | |
| 195 | |
| 196 keypad(cw, TRUE); | |
| 197 keypad(hw, TRUE); | |
| 198 | |
| 199 if (rs_restore_file(inf) == FALSE) | |
| 200 { | |
| 201 endwin(); | |
| 202 printf("Cannot restore file\n"); | |
| 203 close(inf); | |
| 204 return(FALSE); | |
| 205 } | |
| 206 | |
| 207 close(inf); | |
| 208 | |
| 209 if (!wizard) | |
| 210 unlink(file); | |
| 211 | |
| 212 mpos = 0; | |
| 213 environ = envp; | |
| 214 strcpy(file_name, file); | |
| 215 clearok(curscr, TRUE); | |
| 216 touchwin(cw); | |
| 217 wrefresh(cw); | |
| 218 msg("Welcome back! --More-- "); | |
| 219 wait_for(' '); | |
| 220 msg(""); | |
| 221 playit(); | |
| 222 | |
| 223 /*NOTREACHED*/ | |
| 224 return(1); | |
| 225 } | |
| 226 | |
| 227 #define ENCWBSIZ 1024 | |
| 228 | |
| 229 /* | |
| 230 * perform an encrypted write | |
| 231 */ | |
| 232 | |
| 233 long | |
| 234 encwrite(start, size, outf) | |
| 235 register char *start; | |
| 236 register unsigned long size; | |
| 237 register FILE *outf; | |
| 238 { | |
| 239 register unsigned char *ep; | |
| 240 register int i = 0; | |
| 241 unsigned long num_written = 0; | |
| 242 char buf[ENCWBSIZ]; | |
| 243 int ret; | |
| 244 | |
| 245 ep = encstr; | |
| 246 | |
| 247 while (size--) | |
| 248 { | |
| 249 buf[i++] = *start++ ^ *ep++; | |
| 250 if (*ep == '\0') | |
| 251 ep = encstr; | |
| 252 | |
| 253 if (i == ENCWBSIZ || size == 0) | |
| 254 { | |
| 255 ret = (unsigned int) fwrite(buf, 1, i, outf); | |
| 256 if (ret > 0) | |
| 257 num_written += ret; | |
| 258 | |
| 259 if (ret < i) | |
| 260 return(num_written); | |
| 261 | |
| 262 i = 0; | |
| 263 } | |
| 264 } | |
| 265 return(num_written); | |
| 266 } | |
| 267 | |
| 268 #define ENCRBSIZ 32768 | |
| 269 | |
| 270 /* | |
| 271 * perform an encrypted read | |
| 272 */ | |
| 273 | |
| 274 long | |
| 275 encread(start, size, inf) | |
| 276 register char *start; | |
| 277 register unsigned long size; | |
| 278 int inf; | |
| 279 { | |
| 280 register unsigned char *ep; | |
| 281 register int rd_siz; | |
| 282 register unsigned long total_read; | |
| 283 | |
| 284 total_read = 0; | |
| 285 while (total_read < size) { | |
| 286 rd_siz = ENCRBSIZ; | |
| 287 rd_siz = ((size-total_read) > ENCRBSIZ) ? ENCRBSIZ : (size-total_read); | |
| 288 rd_siz = read(inf,&start[total_read],rd_siz); | |
| 289 if(rd_siz==-1 || rd_siz==0) | |
| 290 break; | |
| 291 total_read += rd_siz; | |
| 292 } | |
| 293 ep = encstr; | |
| 294 | |
| 295 size = total_read; | |
| 296 while (size--) | |
| 297 { | |
| 298 *start++ ^= *ep++; | |
| 299 if (*ep == '\0') | |
| 300 ep = encstr; | |
| 301 } | |
| 302 return total_read; | |
| 303 } | |
| 304 |
