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
- savecemetery(fd, mode, &level.bonesinfo);
+ }
+
+ /* 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, &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 */