saving followup

If attempting to checkpoint when changing levels discovered that
the alock.0 or 123wizard.0 file was missing and the game was
running in wizard mode, play continued after reporting trickery
but screen updating was left disabled.  An early return in
savegamestateinlock() wasn't resetting the program_state.saving
flag to revert to normal screen updates.

I added a few return statements at the ends of void routines,
where they're optional, because it makes searching for early
returns easier.  (Without these then when no early return is
present between current point and end of routine, the search
would move past the routine looking for 'return' later in the
file.)

save_stairs() was placed in between saveobj() and saveobjchn()
so I've moved it.  (Has no effect on the recently reported stair
anomalies.)  It was also accumulating the total stairway data
size in 'len' and never using that for anything, so I got rid
of it.  (Ditto about anomalies.)
This commit is contained in:
PatR
2020-12-02 14:49:09 -08:00
parent 4d6a140d34
commit 5e570b181f
+44 -41
View File
@@ -1,4 +1,4 @@
/* NetHack 3.7 save.c $NHDT-Date: 1606919257 2020/12/02 14:27:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.163 $ */ /* NetHack 3.7 save.c $NHDT-Date: 1606949327 2020/12/02 22:48:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.164 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2009. */ /*-Copyright (c) Michael Allison, 2009. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -21,15 +21,12 @@ int dotcnt, dotrow; /* also used in restore */
#endif #endif
static void FDECL(savelevchn, (NHFILE *)); static void FDECL(savelevchn, (NHFILE *));
static void FDECL(savedamage, (NHFILE *));
/* static void FDECL(saveobj, (NHFILE *,struct obj *)); */
/* static void FDECL(savemon, (NHFILE *,struct monst *)); */
/* static void FDECL(savelevl, (NHFILE *, BOOLEAN_P)); */
static void FDECL(saveobj, (NHFILE *,struct obj *));
static void FDECL(savemon, (NHFILE *,struct monst *));
static void FDECL(savelevl, (NHFILE *,BOOLEAN_P)); static void FDECL(savelevl, (NHFILE *,BOOLEAN_P));
static void FDECL(savedamage, (NHFILE *));
static void FDECL(save_stairs, (NHFILE *)); static void FDECL(save_stairs, (NHFILE *));
static void FDECL(saveobj, (NHFILE *,struct obj *));
static void FDECL(saveobjchn, (NHFILE *,struct obj **)); static void FDECL(saveobjchn, (NHFILE *,struct obj **));
static void FDECL(savemon, (NHFILE *,struct monst *));
static void FDECL(savemonchn, (NHFILE *,struct monst *)); static void FDECL(savemonchn, (NHFILE *,struct monst *));
static void FDECL(savetrapchn, (NHFILE *,struct trap *)); static void FDECL(savetrapchn, (NHFILE *,struct trap *));
static void FDECL(savegamestate, (NHFILE *)); static void FDECL(savegamestate, (NHFILE *));
@@ -214,7 +211,7 @@ dosave0()
getlev(onhfp, g.hackpid, ltmp); getlev(onhfp, g.hackpid, ltmp);
close_nhfile(onhfp); close_nhfile(onhfp);
if (nhfp->structlevel) if (nhfp->structlevel)
bwrite(nhfp->fd, (genericptr_t) &ltmp, sizeof ltmp); /* level number*/ bwrite(nhfp->fd, (genericptr_t) &ltmp, sizeof ltmp); /* lvl no. */
savelev(nhfp, ltmp); /* actual level*/ savelev(nhfp, ltmp); /* actual level*/
delete_levelfile(ltmp); delete_levelfile(ltmp);
} }
@@ -242,9 +239,7 @@ NHFILE *nhfp;
unsigned long uid; unsigned long uid;
struct obj *bc_objs = (struct obj *)0; struct obj *bc_objs = (struct obj *)0;
if (!g.program_state.saving) g.program_state.saving++; /* caller should/did already set this... */
impossible("savegamestate called when not saving or changing levels?");
uid = (unsigned long) getuid(); uid = (unsigned long) getuid();
if (nhfp->structlevel) { if (nhfp->structlevel) {
bwrite(nhfp->fd, (genericptr_t) &uid, sizeof uid); bwrite(nhfp->fd, (genericptr_t) &uid, sizeof uid);
@@ -326,8 +321,11 @@ NHFILE *nhfp;
save_msghistory(nhfp); save_msghistory(nhfp);
if (nhfp->structlevel) if (nhfp->structlevel)
bflush(nhfp->fd); bflush(nhfp->fd);
g.program_state.saving--;
return;
} }
/* potentially called from goto_level(do.c) as well as savestateinlock() */
boolean boolean
tricked_fileremoved(nhfp, whynot) tricked_fileremoved(nhfp, whynot)
NHFILE *nhfp; NHFILE *nhfp;
@@ -371,8 +369,10 @@ savestateinlock()
* readable by an external utility * readable by an external utility
*/ */
nhfp = open_levelfile(0, whynot); nhfp = open_levelfile(0, whynot);
if (tricked_fileremoved(nhfp, whynot)) if (tricked_fileremoved(nhfp, whynot)) {
g.program_state.saving--;
return; return;
}
if (nhfp->structlevel) if (nhfp->structlevel)
(void) read(nhfp->fd, (genericptr_t) &hpid, sizeof hpid); (void) read(nhfp->fd, (genericptr_t) &hpid, sizeof hpid);
@@ -420,6 +420,7 @@ savestateinlock()
} }
g.program_state.saving--; g.program_state.saving--;
g.havestate = flags.ins_chkpt; g.havestate = flags.ins_chkpt;
return;
} }
#endif #endif
@@ -537,6 +538,7 @@ xchar lev;
bflush(nhfp->fd); bflush(nhfp->fd);
} }
g.program_state.saving--; g.program_state.saving--;
return;
} }
static void static void
@@ -598,6 +600,7 @@ boolean rlecomp;
if (nhfp->structlevel) { if (nhfp->structlevel) {
bwrite(nhfp->fd, (genericptr_t) levl, sizeof levl); bwrite(nhfp->fd, (genericptr_t) levl, sizeof levl);
} }
return;
} }
/* used when saving a level and also when saving dungeon overview data */ /* used when saving a level and also when saving dungeon overview data */
@@ -656,6 +659,32 @@ NHFILE *nhfp;
g.level.damagelist = 0; g.level.damagelist = 0;
} }
static void
save_stairs(nhfp)
NHFILE *nhfp;
{
stairway *stway = g.stairs;
int buflen = (int) sizeof *stway;
while (stway) {
if (perform_bwrite(nhfp)) {
if (nhfp->structlevel) {
bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen);
bwrite(nhfp->fd, (genericptr_t) stway, sizeof *stway);
}
}
stway = stway->next;
}
if (perform_bwrite(nhfp)) {
if (nhfp->structlevel) {
buflen = -1;
bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen);
}
}
}
/* save one object;
caveat: this is only for perform_bwrite(); caller handles release_data() */
static void static void
saveobj(nhfp, otmp) saveobj(nhfp, otmp)
NHFILE *nhfp; NHFILE *nhfp;
@@ -694,40 +723,14 @@ struct obj *otmp;
} }
/* omid used to be indirect via a pointer in oextra but has /* omid used to be indirect via a pointer in oextra but has
become part of oextra itself; 0 means not applicable and become part of oextra itself; 0 means not applicable and
gets saved/restored whenever any other oxtra components do */ gets saved/restored whenever any other oextra components do */
if (nhfp->structlevel) if (nhfp->structlevel)
bwrite(nhfp->fd, (genericptr_t) &OMID(otmp), sizeof OMID(otmp)); bwrite(nhfp->fd, (genericptr_t) &OMID(otmp), sizeof OMID(otmp));
} }
} }
static void /* save an object chain; sets head of list to Null when done;
save_stairs(nhfp) handles release_data() for each object in the list */
NHFILE *nhfp;
{
stairway *stway = g.stairs;
int buflen = (int) sizeof (stairway);
int len = 0;
while (stway) {
if (perform_bwrite(nhfp)) {
if (nhfp->structlevel) {
len += sizeof(buflen);
bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen);
len += sizeof(stairway);
bwrite(nhfp->fd, (genericptr_t) stway, sizeof(stairway));
}
}
stway = stway->next;
}
if (perform_bwrite(nhfp)) {
if (nhfp->structlevel) {
buflen = -1;
len += sizeof(buflen);
bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen);
}
}
}
static void static void
saveobjchn(nhfp, obj_p) saveobjchn(nhfp, obj_p)
NHFILE *nhfp; NHFILE *nhfp;