]> granicus.if.org Git - nethack/commitdiff
Merge branch 'NetHack-3.6' into NetHack-3.7
authorPatric Mueller <bhaak@gmx.net>
Sun, 26 May 2019 16:16:22 +0000 (18:16 +0200)
committerPatric Mueller <bhaak@gmx.net>
Sun, 26 May 2019 16:16:22 +0000 (18:16 +0200)
1  2 
src/save.c

diff --cc src/save.c
index bb88bf8a2274e1286ab2f5b584d57c8efebdc2ac,b1e31bc49c80ecb51e299fd79599f75a8e6fdd80..d5c6003e4edba8bd9f30d9d5138a6a9673740f77
@@@ -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
 -    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 */