1 /* 2 * save and restore routines 3 * 4 * save.c 1.32 (A.I. Design) 12/13/84 5 */ 6 7 /* 8 * routines for saving a program in any given state. 9 * This is the first pass of this, so I have no idea 10 * how it is really going to work. 11 * The two basic functions here will be "save" and "restor". 12 */ 13 14 #include "rogue.h" 15 #include "curses.h" 16 17 /* 18 * we need to know location of screen being saved 19 */ 20 extern char *savewin; 21 extern int errno; 22 extern char _lowmem; /* Adresss of first save-able memory */ 23 extern char _Uend; /* Address of end of user data space */ 24 extern char do_force; 25 extern int bwflag; 26 27 #define MIDSIZE 10 28 char *msaveid = "AI Design"; 29 30 #define printf printw 31 /* 32 * BLKSZ: size of block read/written on each io operation 33 * Has to be less than 4096 and a factor of 4096 34 * so the screen can be read in exactly. 35 */ 36 #define BLKSZ 512 37 38 /* 39 * save_game: 40 * Implement the "save game" command 41 */ 42 save_game() 43 { 44 #ifndef DEMO 45 register int retcode; 46 char savename[20]; 47 48 msg(""); 49 mpos = 0; 50 if (terse) 51 addstr("Save file ? "); 52 else 53 printw("Save file (press enter (\x11\xd9) to default to \"%s\") ? ", 54 s_save ); 55 retcode = getinfo(savename,19); 56 if (*savename == 0) 57 strcpy(savename,s_save); 58 msg(""); 59 mpos = 0; 60 if (retcode != ESCAPE) 61 { 62 if ((retcode = save_ds(savename)) == -1) 63 { 64 if (unlink(savename) == 0) 65 ifterse1("out of space?","out of space, can not write %s",savename); 66 msg("Sorry, you can't save the game just now"); 67 is_saved = FALSE; 68 } 69 else if (retcode > 0) 70 fatal("\nGame saved as %s.", savename); 71 } 72 #endif 73 } 74 #ifndef DEMO 75 /* 76 * Save: 77 * Determine the entire data area that needs to be saved, 78 * Open save file, first write in to save file a header 79 * that demensions the data area that will be saved, 80 * and then dump data area determined previous to opening 81 * file. 82 */ 83 save_ds(savename) 84 char *savename; 85 { 86 register int sfd; 87 register char answer; 88 89 if ((sfd = open(savename, 0)) >= 0) 90 { 91 close(sfd); 92 msg("%s %sexists, overwrite (y/n) ?",savename,noterse("already ")); 93 answer = readchar(); 94 msg(""); 95 if ((answer != 'y') && (answer != 'Y')) 96 return(-2); 97 } 98 99 if ((sfd = creat(savename, 0666)) <= 0) 100 { 101 msg("Could not creat %s",savename); 102 return (-2); 103 } 104 is_saved = TRUE; 105 mpos = 0; 106 107 errno = 1; 108 if (write(sfd,msaveid,MIDSIZE) != MIDSIZE 109 || write(sfd, &_lowmem , &_Uend - &_lowmem) != &_Uend-&_lowmem 110 || write(sfd, end_sb, startmem - end_sb) != startmem - end_sb) 111 goto wr_err; 112 /* 113 * save the screen (have to bring it into current data segment first) 114 */ 115 wdump(); 116 if (write(sfd,savewin,4000) == 4000) 117 errno = 0; 118 wrestor(); 119 120 wr_err: 121 close(sfd); 122 switch (errno) 123 { 124 default: 125 msg("Could not write savefile to disk!"); 126 return -1; 127 case 0: 128 move(24,0); 129 clrtoeol(); 130 move(23,0); 131 return 1; 132 } 133 } 134 #endif DEMO 135 /* 136 * Restore: 137 * Open saved data file, read in header, and determine how much 138 * data area is going to be restored, 139 * Close save data file, 140 * Allocate enough data space so that open data file information 141 * will be stored outside the data area that will be restored, 142 * Now reopen data save file, 143 * skip header, 144 * dump into memory all saved data. 145 */ 146 restore(savefile) 147 char *savefile; 148 { 149 #ifndef DEMO 150 int oldrev, oldver, old_check; 151 register int oldcols, fd; 152 char errbuf[11], save_name[MAXSTR]; 153 char *read_error = "Read Error"; 154 struct sw_regs *oregs; 155 unsigned nbytes; 156 char idbuf[MIDSIZE]; 157 158 oregs = regs; 159 winit(); 160 if (bwflag) 161 forcebw(); 162 if (no_check == 0) 163 no_check = do_force; 164 old_check = no_check; 165 strcpy(errbuf,read_error); 166 /* 167 * save things that will be bombed on when the 168 * restor takes place 169 */ 170 oldrev = revno; 171 oldver = verno; 172 173 if (!strcmp(s_drive,"?")) 174 { 175 int ot = scr_type; 176 printw("Press space to restart game"); 177 scr_type = -1; 178 wait_for(' '); 179 scr_type = ot; 180 addstr("\n"); 181 } 182 if ((fd = open(savefile, 0)) < 0) 183 fatal("%s not found\n",savefile); 184 else 185 printf("Restoring %s",savefile); 186 strcpy(save_name, savefile); 187 nbytes = &_Uend - &_lowmem; 188 if (read(fd,idbuf,MIDSIZE) != MIDSIZE || strcmp(idbuf,msaveid) ) 189 addstr("\nNot a savefile\n"); 190 else 191 { 192 if (read(fd, &_lowmem, nbytes) == nbytes) 193 if (read(fd, end_sb,nbytes=startmem-end_sb) == nbytes) 194 goto rok; 195 addstr(errbuf); 196 } 197 close(fd); 198 exit(); 199 200 rok: 201 regs = oregs; 202 if (revno != oldrev || verno != oldver) 203 { 204 close(fd); 205 exit(); 206 } 207 208 oldcols = COLS; 209 brk(end_sb); /* Restore heap to empty state */ 210 init_ds(); 211 wclose(); 212 winit(); 213 if (oldcols != COLS) 214 { 215 close(fd); 216 fatal("Restore Error: new screen size\n"); 217 } 218 219 wdump(); 220 if (read(fd,savewin,4000) != 4000) 221 { 222 close(fd); 223 fatal("Serious restore error"); 224 } 225 wrestor(); 226 227 close (fd); 228 no_check = old_check; 229 mpos = 0; 230 ifterse1("%s, Welcome back!","Hello %s, Welcome back to the Dungeons of Doom!",whoami); 231 dnum = srand(); /* make it a little tougher on cheaters */ 232 unlink(save_name); 233 #endif DEMO 234 } 235 ÿ