From: Patric Mueller Date: Sun, 26 May 2019 16:16:22 +0000 (+0200) Subject: Merge branch 'NetHack-3.6' into NetHack-3.7 X-Git-Tag: NetHack-3.7.0_WIP~401 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f7a2b9a8dce4dc0dddc7fee50e4cf518294ed903;p=nethack Merge branch 'NetHack-3.6' into NetHack-3.7 --- f7a2b9a8dce4dc0dddc7fee50e4cf518294ed903 diff --cc src/save.c index bb88bf8a2,b1e31bc49..d5c6003e4 --- a/src/save.c +++ b/src/save.c @@@ -472,47 -475,71 +471,71 @@@ int mode short tlev; #endif - /* if we're tearing down the current level without saving anything - (which happens upon entrance to the endgame or after an aborted - restore attempt) then we don't want to do any actual I/O */ - if (mode == FREE_SAVE) - goto skip_lots; + /* + * Level file contents: + * version info (handled by caller); + * save file info (compression type; also by caller); + * process ID; + * internal level number (ledger number); + * bones info; + * actual level data. + * + * If we're tearing down the current level without saving anything + * (which happens at end of game or upon entrance to endgame or + * after an aborted restore attempt) then we don't want to do any + * actual I/O. So when only freeing, we skip to the bones info + * portion (which has some freeing to do), then jump quite a bit + * further ahead to the middle of the 'actual level data' portion. + */ + if (mode != FREE_SAVE) { + /* WRITE_SAVE (probably ORed with FREE_SAVE), or COUNT_SAVE */ - /* purge any dead monsters (necessary if we're starting - a panic save rather than a normal one, or sometimes - when changing levels without taking time -- e.g. - create statue trap then immediately level teleport) */ - if (iflags.purge_monsters) - dmonsfree(); + /* purge any dead monsters (necessary if we're starting + a panic save rather than a normal one, or sometimes + when changing levels without taking time -- e.g. + create statue trap then immediately level teleport) */ + if (iflags.purge_monsters) + dmonsfree(); - if (fd < 0) - panic("Save on bad file!"); /* impossible */ + if (fd < 0) + panic("Save on bad file!"); /* impossible */ #ifdef MFLOPPY - count_only = (mode & COUNT_SAVE); + count_only = (mode & COUNT_SAVE); #endif - if (lev >= 0 && lev <= maxledgerno()) - g.level_info[lev].flags |= VISITED; - bwrite(fd, (genericptr_t) &g.hackpid, sizeof g.hackpid); + if (lev >= 0 && lev <= maxledgerno()) - level_info[lev].flags |= VISITED; - bwrite(fd, (genericptr_t) &hackpid, sizeof hackpid); ++ g.level_info[lev].flags |= VISITED; ++ bwrite(fd, (genericptr_t) &g.hackpid, sizeof g.hackpid); #ifdef TOS - tlev = lev; - tlev &= 0x00ff; - bwrite(fd, (genericptr_t) &tlev, sizeof tlev); + tlev = lev; + tlev &= 0x00ff; + bwrite(fd, (genericptr_t) &tlev, sizeof tlev); #else - bwrite(fd, (genericptr_t) &lev, sizeof lev); + bwrite(fd, (genericptr_t) &lev, sizeof lev); #endif + } + + /* bones info comes before level data; the intent is for an external + program ('hearse') to be able to match a bones file with the + corresponding log file entry--or perhaps just skip that?--without + the guessing that was needed in 3.4.3 and without having to + interpret level data to find where to start; unfortunately it + still needs to handle all the data compression schemes */ - savecemetery(fd, mode, &level.bonesinfo); + savecemetery(fd, mode, &g.level.bonesinfo); + if (mode == FREE_SAVE) /* see above */ + goto skip_lots; + savelevl(fd, (boolean) ((sfsaveinfo.sfi1 & SFI1_RLECOMP) == SFI1_RLECOMP)); - bwrite(fd, (genericptr_t) lastseentyp, sizeof lastseentyp); - bwrite(fd, (genericptr_t) &monstermoves, sizeof monstermoves); - bwrite(fd, (genericptr_t) &upstair, sizeof (stairway)); - bwrite(fd, (genericptr_t) &dnstair, sizeof (stairway)); - bwrite(fd, (genericptr_t) &upladder, sizeof (stairway)); - bwrite(fd, (genericptr_t) &dnladder, sizeof (stairway)); - bwrite(fd, (genericptr_t) &sstairs, sizeof (stairway)); - bwrite(fd, (genericptr_t) &updest, sizeof (dest_area)); - bwrite(fd, (genericptr_t) &dndest, sizeof (dest_area)); - bwrite(fd, (genericptr_t) &level.flags, sizeof level.flags); - bwrite(fd, (genericptr_t) doors, sizeof doors); + bwrite(fd, (genericptr_t) g.lastseentyp, sizeof g.lastseentyp); + bwrite(fd, (genericptr_t) &g.monstermoves, sizeof g.monstermoves); + bwrite(fd, (genericptr_t) &g.upstair, sizeof (stairway)); + bwrite(fd, (genericptr_t) &g.dnstair, sizeof (stairway)); + bwrite(fd, (genericptr_t) &g.upladder, sizeof (stairway)); + bwrite(fd, (genericptr_t) &g.dnladder, sizeof (stairway)); + bwrite(fd, (genericptr_t) &g.sstairs, sizeof (stairway)); + bwrite(fd, (genericptr_t) &g.updest, sizeof (dest_area)); + bwrite(fd, (genericptr_t) &g.dndest, sizeof (dest_area)); + bwrite(fd, (genericptr_t) &g.level.flags, sizeof g.level.flags); + bwrite(fd, (genericptr_t) g.doors, sizeof g.doors); save_rooms(fd); /* no dynamic memory to reclaim */ /* from here on out, saving also involves allocated memory cleanup */