updated files
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 cmd.c $NHDT-Date: 1561017215 2019/06/20 07:53:35 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.337 $ */
|
||||
/* NetHack 3.6 cmd.c $NHDT-Date: 1560789049 2019/06/17 16:30:49 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.336 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2013. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -4571,8 +4571,7 @@ randomkey()
|
||||
c = (char) rn1('9' - '0' + 1, '0');
|
||||
break;
|
||||
case 14:
|
||||
/* any char, but avoid '\0' because it's used for mouse click */
|
||||
c = (char) rnd(iflags.wc_eight_bit_input ? 255 : 127);
|
||||
c = (char) rn2(iflags.wc_eight_bit_input ? 256 : 128);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -418,9 +418,6 @@ const struct instance_globals g_init = {
|
||||
FALSE, /* chosen_symset_start */
|
||||
FALSE, /* chosen_symset_end */
|
||||
0, /* symset_which_set */
|
||||
#ifdef HOLD_LOCKFILE_OPEN
|
||||
DUMMY, /* lftrack */
|
||||
#endif
|
||||
DUMMY, /* SAVEF */
|
||||
#ifdef MICRO
|
||||
DUMMY, /* SAVEP */
|
||||
|
||||
6
src/do.c
6
src/do.c
@@ -1166,7 +1166,8 @@ save_currentstate()
|
||||
nhfp = currentlevel_rewrite();
|
||||
if (!nhfp)
|
||||
return;
|
||||
bufon(nhfp->fd);
|
||||
if (nhfp->structlevel)
|
||||
bufon(nhfp->fd);
|
||||
nhfp->mode = WRITING;
|
||||
savelev(nhfp,ledger_no(&u.uz));
|
||||
close_nhfile(nhfp);
|
||||
@@ -1362,7 +1363,8 @@ boolean at_stairs, falling, portal;
|
||||
cant_go_back = (newdungeon && In_endgame(newlevel));
|
||||
if (!cant_go_back) {
|
||||
update_mlstmv(); /* current monsters are becoming inactive */
|
||||
bufon(nhfp->fd); /* use buffered output */
|
||||
if (nhfp->structlevel)
|
||||
bufon(nhfp->fd); /* use buffered output */
|
||||
}
|
||||
save_mode = nhfp->mode;
|
||||
nhfp->mode = cant_go_back ? FREEING : (WRITING | FREEING);
|
||||
|
||||
@@ -46,7 +46,7 @@ STATIC_DCL void NDECL(dump_plines);
|
||||
STATIC_DCL void FDECL(dump_everything, (int, time_t));
|
||||
STATIC_DCL int NDECL(num_extinct);
|
||||
|
||||
#if defined(__BEOS__) || defined(MICRO) || defined(OS2)
|
||||
#if defined(__BEOS__) || defined(MICRO) || defined(OS2) || defined(WIN32)
|
||||
extern void FDECL(nethack_exit, (int));
|
||||
#else
|
||||
#define nethack_exit exit
|
||||
|
||||
272
src/files.c
272
src/files.c
@@ -80,11 +80,9 @@ static char fqn_filename_buffer[FQN_NUMBUF][FQN_MAX_FILENAME];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HOLD_LOCKFILE_OPEN
|
||||
#if defined(WIN32)
|
||||
#include <share.h>
|
||||
#endif
|
||||
#endif /*HOLD_LOCKFILE_OPEN*/
|
||||
|
||||
STATIC_DCL FILE *NDECL(fopen_wizkit_file);
|
||||
STATIC_DCL void FDECL(wizkit_addinv, (struct obj *));
|
||||
@@ -169,9 +167,6 @@ STATIC_DCL void FDECL(parseformat, (int *, char *));
|
||||
#ifdef SELF_RECOVER
|
||||
STATIC_DCL boolean FDECL(copy_bytes, (int, int));
|
||||
#endif
|
||||
#ifdef HOLD_LOCKFILE_OPEN
|
||||
STATIC_DCL int FDECL(open_levelfile_exclusively, (const char *, int, int));
|
||||
#endif
|
||||
STATIC_DCL NHFILE *FDECL(viable_nhfile, (NHFILE *));
|
||||
|
||||
/*
|
||||
@@ -415,25 +410,6 @@ NHFILE *nhfp;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
E void FDECL(sfi_init, (struct sf_procs *));
|
||||
E void FDECL(sfo_init, (struct sf_procs *));
|
||||
E struct sf_procs sfoprocs, sfiprocs;
|
||||
#ifdef SYSCF
|
||||
if (sysopt.saveformat[0] > 1) {
|
||||
/* initialize the function pointers for fieldlevel saves */
|
||||
if (sysopt.saveformat[0] == lendian) {
|
||||
sfi_init(&lendian_sfi_procs);
|
||||
sfo_init(&lendian_sfo_procs);
|
||||
}
|
||||
if (sysopt.saveformat[0] == ascii) {
|
||||
sfi_init(&ascii_sfi_procs);
|
||||
sfo_init(&ascii_sfo_procs);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
NHFILE *
|
||||
new_nhfile()
|
||||
{
|
||||
@@ -465,7 +441,7 @@ NHFILE *nhfp;
|
||||
(void) fclose(nhfp->fpdef);
|
||||
nhfp->fpdef = (FILE *) 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nhfp->fplog)
|
||||
(void) fprintf(nhfp->fplog, "# closing\n");
|
||||
if (nhfp->fplog)
|
||||
@@ -493,7 +469,7 @@ NHFILE *nhfp;
|
||||
rewind(nhfp->fpdef);
|
||||
nhfp->count = 0L;
|
||||
nhfp->eof = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -610,13 +586,7 @@ char errbuf[];
|
||||
/* Use O_TRUNC to force the file to be shortened if it already
|
||||
* exists and is currently longer.
|
||||
*/
|
||||
#ifdef HOLD_LOCKFILE_OPEN
|
||||
if (lev == 0)
|
||||
nhfp->fd = open_levelfile_exclusively(
|
||||
fq_lock, lev, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY);
|
||||
else
|
||||
#endif
|
||||
nhfp->fd = open(fq_lock, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, FCMASK);
|
||||
nhfp->fd = open(fq_lock, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, FCMASK);
|
||||
#else
|
||||
#ifdef MAC
|
||||
nhfp->fd = maccreat(fq_lock, LEVL_TYPE);
|
||||
@@ -668,12 +638,7 @@ char errbuf[];
|
||||
#ifdef MAC
|
||||
nhfp->fd = macopen(fq_lock, O_RDONLY | O_BINARY, LEVL_TYPE);
|
||||
#else
|
||||
#ifdef HOLD_LOCKFILE_OPEN
|
||||
if (lev == 0)
|
||||
nhfp->fd = open_levelfile_exclusively(fq_lock, lev, O_RDONLY | O_BINARY);
|
||||
else
|
||||
#endif
|
||||
nhfp->fd = open(fq_lock, O_RDONLY | O_BINARY, 0);
|
||||
nhfp->fd = open(fq_lock, O_RDONLY | O_BINARY, 0);
|
||||
#endif
|
||||
|
||||
/* for failure, return an explanation that our caller can use;
|
||||
@@ -697,10 +662,6 @@ int lev;
|
||||
*/
|
||||
if (lev == 0 || (g.level_info[lev].flags & LFILE_EXISTS)) {
|
||||
set_levelfile_name(g.lock, lev);
|
||||
#ifdef HOLD_LOCKFILE_OPEN
|
||||
if (lev == 0)
|
||||
really_close();
|
||||
#endif
|
||||
(void) unlink(fqname(g.lock, LEVELPREFIX, 0));
|
||||
g.level_info[lev].flags &= ~LFILE_EXISTS;
|
||||
}
|
||||
@@ -749,88 +710,20 @@ const void *q;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HOLD_LOCKFILE_OPEN
|
||||
STATIC_OVL int
|
||||
open_levelfile_exclusively(name, lev, oflag)
|
||||
const char *name;
|
||||
int lev, oflag;
|
||||
{
|
||||
int reslt, fd;
|
||||
|
||||
if (!g.lftrack.init) {
|
||||
g.lftrack.init = 1;
|
||||
g.lftrack.fd = -1;
|
||||
}
|
||||
if (g.lftrack.fd >= 0) {
|
||||
/* check for compatible access */
|
||||
if (g.lftrack.oflag == oflag) {
|
||||
fd = g.lftrack.fd;
|
||||
reslt = lseek(fd, 0L, SEEK_SET);
|
||||
if (reslt == -1L)
|
||||
panic("open_levelfile_exclusively: lseek failed %d", errno);
|
||||
g.lftrack.nethack_thinks_it_is_open = TRUE;
|
||||
} else {
|
||||
really_close();
|
||||
fd = sopen(name, oflag, SH_DENYRW, FCMASK);
|
||||
g.lftrack.fd = fd;
|
||||
g.lftrack.oflag = oflag;
|
||||
g.lftrack.nethack_thinks_it_is_open = TRUE;
|
||||
}
|
||||
} else {
|
||||
fd = sopen(name, oflag, SH_DENYRW, FCMASK);
|
||||
g.lftrack.fd = fd;
|
||||
g.lftrack.oflag = oflag;
|
||||
if (fd >= 0)
|
||||
g.lftrack.nethack_thinks_it_is_open = TRUE;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
void
|
||||
really_close()
|
||||
{
|
||||
int fd;
|
||||
|
||||
if (g.lftrack.init) {
|
||||
fd = g.lftrack.fd;
|
||||
|
||||
g.lftrack.nethack_thinks_it_is_open = FALSE;
|
||||
g.lftrack.fd = -1;
|
||||
g.lftrack.oflag = 0;
|
||||
if (fd != -1)
|
||||
(void) close(fd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
nhclose(fd)
|
||||
int fd;
|
||||
{
|
||||
NHFILE *nhfp, tnhfp;
|
||||
int retval = 0;
|
||||
|
||||
if (g.lftrack.fd == fd) {
|
||||
really_close(); /* close it, but reopen it to hold it */
|
||||
nhfp = open_levelfile(0, (char *) 0);
|
||||
if (nhfp) {
|
||||
tnhfp = *nhfp;
|
||||
free(nhfp);
|
||||
g.lftrack.fd = tnhfp.fd;
|
||||
}
|
||||
g.lftrack.nethack_thinks_it_is_open = FALSE;
|
||||
return 0;
|
||||
if (fd >= 0) {
|
||||
if (close_check(fd))
|
||||
bclose(fd);
|
||||
else
|
||||
retval = close(fd);
|
||||
}
|
||||
return close(fd);
|
||||
return retval;
|
||||
}
|
||||
#else /* !HOLD_LOCKFILE_OPEN */
|
||||
|
||||
int
|
||||
nhclose(fd)
|
||||
int fd;
|
||||
{
|
||||
return close(fd);
|
||||
}
|
||||
#endif /* ?HOLD_LOCKFILE_OPEN */
|
||||
|
||||
/* ---------- END LEVEL FILE HANDLING ----------- */
|
||||
|
||||
@@ -974,7 +867,7 @@ char errbuf[];
|
||||
#endif
|
||||
if (nhfp->fd < 0)
|
||||
failed = errno;
|
||||
}
|
||||
}
|
||||
if (failed && errbuf) /* failure explanation */
|
||||
Sprintf(errbuf, "Cannot create bones \"%s\", id %s (errno %d).",
|
||||
g.lock, *bonesid, errno);
|
||||
@@ -1114,70 +1007,98 @@ void
|
||||
set_savefile_name(regularize_it)
|
||||
boolean regularize_it;
|
||||
{
|
||||
int idx = 0;
|
||||
int idx = 0, regoffset = 0, overflow = 0,
|
||||
indicator_spot = 0; /* 0=no indicator, 1=before ext, 2=after ext */
|
||||
const char *postappend = (const char *) 0,
|
||||
*sfindicator = (const char *) 0;
|
||||
|
||||
#ifdef VMS
|
||||
Sprintf(g.SAVEF, "[.save]%d%s", getuid(), g.plname);
|
||||
#ifdef SYSCF
|
||||
idx = sysopt.saveformat[0];
|
||||
if (idx > historical && idx <= ascii)
|
||||
Strcat(g.SAVEF, sfoprocs[idx].ext);
|
||||
sfindicator = sfoprocs[idx].ext;
|
||||
#endif
|
||||
if (regularize_it)
|
||||
regularize(g.SAVEF + 7);
|
||||
Strcat(g.SAVEF, ";1");
|
||||
#else
|
||||
#if defined(MICRO)
|
||||
Strcpy(g.SAVEF, g.SAVEP);
|
||||
#ifdef VMS
|
||||
Sprintf(g.SAVEF, "[.save]%d%s", getuid(), g.plname);
|
||||
regoffset = 7;
|
||||
indicator_spot = 1;
|
||||
postappend = ";1");
|
||||
#endif
|
||||
#if defined(WIN32)
|
||||
if (regularize_it) {
|
||||
static const char okchars[] =
|
||||
"*ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-.";
|
||||
const char *legal = okchars;
|
||||
char tmp[BUFSZ];
|
||||
|
||||
++legal; /* skip '*' wildcard character */
|
||||
(void) fname_encode(legal, '%', g.plname, tmp, sizeof tmp);
|
||||
if (strlen(tmp) < (SAVESIZE - 1))
|
||||
Strcpy(g.SAVEF, tmp);
|
||||
else
|
||||
overflow = 1;
|
||||
indicator_spot = 1;
|
||||
regularize_it = FALSE;
|
||||
}
|
||||
#endif
|
||||
#ifdef UNIX
|
||||
Sprintf(g.SAVEF, "save/%d%s", (int) getuid(), g.plname);
|
||||
regoffset = 5;
|
||||
indicator_spot = 2;
|
||||
#endif
|
||||
#if defined(MICRO) && !defined(VMS) && !defined(WIN32)
|
||||
if (strlen(g.SAVEP) < (SAVESIZE - 1))
|
||||
Strcpy(g.SAVEF, g.SAVEP);
|
||||
else
|
||||
#ifdef AMIGA
|
||||
strncat(g.SAVEF, bbs_id, PATHLEN);
|
||||
if (strlen(g.SAVEP) + strlen(bbs_id) < (SAVESIZE - 1))
|
||||
strncat(g.SAVEF, bbs_id, PATHLEN);
|
||||
#endif
|
||||
{
|
||||
int i = strlen(g.SAVEP);
|
||||
#ifdef AMIGA
|
||||
/* g.plname has to share space with g.SAVEP and ".sav" */
|
||||
(void) strncat(g.SAVEF, g.plname, FILENAME - i - 4);
|
||||
(void) strncat(g.SAVEF, g.plname,
|
||||
FILENAME - i - strlen(SAVE_EXTENSION));
|
||||
#else
|
||||
(void) strncat(g.SAVEF, g.plname, 8);
|
||||
#endif
|
||||
#ifdef SYSCF
|
||||
idx = sysopt.saveformat[0];
|
||||
if (idx > historical && idx <= ascii)
|
||||
Strcat(g.SAVEF, sfoprocs[idx].ext);
|
||||
#endif
|
||||
if (regularize_it)
|
||||
regularize(g.SAVEF + i);
|
||||
regoffset = i;
|
||||
}
|
||||
Strcat(g.SAVEF, SAVE_EXTENSION);
|
||||
#else
|
||||
#if defined(WIN32)
|
||||
{
|
||||
static const char okchars[] =
|
||||
"*ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-.";
|
||||
const char *legal = okchars;
|
||||
|
||||
if (regularize_it)
|
||||
++legal; /* skip '*' wildcard character */
|
||||
(void) fname_encode(legal, '%', g.plname, g.SAVEF, sizeof g.SAVEF);
|
||||
Strcat(g.SAVEF, SAVE_EXTENSION);
|
||||
#ifdef SYSCF
|
||||
idx = sysopt.saveformat[0];
|
||||
if (idx > historical && idx <= ascii)
|
||||
Strcat(g.SAVEF, sfoprocs[idx].ext);
|
||||
#endif
|
||||
}
|
||||
#else /* not VMS or MICRO or WIN32 */
|
||||
Sprintf(g.SAVEF, "save/%d%s", (int) getuid(), g.plname);
|
||||
#ifdef SYSCF
|
||||
idx = sysopt.saveformat[0];
|
||||
if (idx > historical && idx <= ascii)
|
||||
Strcat(g.SAVEF, sfoprocs[idx].ext);
|
||||
#endif
|
||||
if (regularize_it)
|
||||
regularize(g.SAVEF + 5); /* avoid . or / in name */
|
||||
#endif /* WIN32 */
|
||||
#endif /* MICRO */
|
||||
#endif /* VMS */
|
||||
|
||||
if (regularize_it)
|
||||
regularize(g.SAVEF + regoffset);
|
||||
if (indicator_spot == 1 && sfindicator && !overflow) {
|
||||
if (strlen(g.SAVEF) + strlen(sfindicator) < (SAVESIZE - 1))
|
||||
Strcat(g.SAVEF, sfindicator);
|
||||
else
|
||||
overflow = 2;
|
||||
}
|
||||
#ifdef SAVE_EXTENSION
|
||||
if (strlen(SAVE_EXTENSION) > 0 && !overflow) {
|
||||
if (strlen(g.SAVEF) + strlen(SAVE_EXTENSION) < (SAVESIZE - 1))
|
||||
Strcat(g.SAVEF, SAVE_EXTENSION);
|
||||
else
|
||||
overflow = 3;
|
||||
}
|
||||
#endif
|
||||
if (indicator_spot == 2 && sfindicator && !overflow) {
|
||||
if (strlen(g.SAVEF) + strlen(sfindicator) < (SAVESIZE - 1))
|
||||
Strcat(g.SAVEF, sfindicator);
|
||||
else
|
||||
overflow = 4;
|
||||
}
|
||||
if (postappend && !overflow) {
|
||||
if (strlen(g.SAVEF) + strlen(postappend) < (SAVESIZE - 1))
|
||||
Strcat(g.SAVEF, postappend);
|
||||
else
|
||||
overflow = 5;
|
||||
}
|
||||
#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED)
|
||||
if (overflow)
|
||||
impossible("set_savefile_name() couldn't complete without overlow %d",
|
||||
overflow);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef INSURANCE
|
||||
@@ -1229,10 +1150,10 @@ create_savefile()
|
||||
nhfp->structlevel = TRUE;
|
||||
nhfp->fieldlevel = FALSE;
|
||||
nhfp->ftype = NHF_SAVEFILE;
|
||||
nhfp->mode = WRITING;
|
||||
#ifdef SYSCF
|
||||
if (sysopt.saveformat[0] > historical &&
|
||||
sysopt.saveformat[0] <= ascii) {
|
||||
nhfp->mode = WRITING;
|
||||
nhfp->structlevel = FALSE;
|
||||
nhfp->fieldlevel = TRUE;
|
||||
nhfp->addinfo = TRUE;
|
||||
@@ -1248,7 +1169,7 @@ create_savefile()
|
||||
} else {
|
||||
failed = errno;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* SYSCF */
|
||||
if (nhfp->structlevel) {
|
||||
#if defined(MICRO) || defined(WIN32)
|
||||
@@ -1262,7 +1183,7 @@ create_savefile()
|
||||
#endif /* MICRO || WIN32 */
|
||||
if (nhfp->fd < 0)
|
||||
failed = errno;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if defined(VMS) && !defined(SECURE)
|
||||
/*
|
||||
@@ -1293,10 +1214,10 @@ open_savefile()
|
||||
nhfp->structlevel = TRUE;
|
||||
nhfp->fieldlevel = FALSE;
|
||||
nhfp->ftype = NHF_SAVEFILE;
|
||||
nhfp->mode = READING;
|
||||
#ifdef SYSCF
|
||||
if (sysopt.saveformat[0] > historical &&
|
||||
sysopt.saveformat[0] <= ascii) {
|
||||
nhfp->mode = READING;
|
||||
nhfp->structlevel = FALSE;
|
||||
nhfp->fieldlevel = TRUE;
|
||||
nhfp->addinfo = TRUE;
|
||||
@@ -1343,7 +1264,6 @@ restore_saved_game()
|
||||
const char *fq_save;
|
||||
NHFILE *nhfp = (NHFILE *) 0;
|
||||
|
||||
reset_restpref();
|
||||
set_savefile_name(TRUE);
|
||||
#ifdef MFLOPPY
|
||||
if (!saveDiskPrompt(1))
|
||||
@@ -3708,7 +3628,7 @@ char *str;
|
||||
while (*p && isspace((uchar) *p)) {
|
||||
*p = '\0';
|
||||
p++;
|
||||
}
|
||||
}
|
||||
if (*p) {
|
||||
words++;
|
||||
if (kwi < 2)
|
||||
@@ -3726,7 +3646,7 @@ char *str;
|
||||
for (i = 0; i < SIZE(legal); ++i) {
|
||||
if (!strcmpi(keywords[kwi], legal[i]))
|
||||
arr[kwi] = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4081,10 +4001,6 @@ recover_savefile()
|
||||
}
|
||||
}
|
||||
close_nhfile(snhfp);
|
||||
|
||||
#ifdef HOLD_LOCKFILE_OPEN
|
||||
really_close();
|
||||
#endif
|
||||
/*
|
||||
* We have a successful savefile!
|
||||
* Only now do we erase the level files.
|
||||
|
||||
51
src/minion.c
51
src/minion.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 minion.c $NHDT-Date: 1561061319 2019/06/20 20:08:39 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.42 $ */
|
||||
/* NetHack 3.6 minion.c $NHDT-Date: 1544998886 2018/12/16 22:21:26 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.40 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2008. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -204,13 +204,9 @@ boolean talk;
|
||||
}
|
||||
if (mon) {
|
||||
if (talk) {
|
||||
if (!Deaf)
|
||||
pline_The("voice of %s booms:", align_gname(alignment));
|
||||
else
|
||||
You_feel("%s booming voice:",
|
||||
s_suffix(align_gname(alignment)));
|
||||
pline_The("voice of %s booms:", align_gname(alignment));
|
||||
verbalize("Thou shalt pay for thine indiscretion!");
|
||||
if (canspotmon(mon))
|
||||
if (!Blind)
|
||||
pline("%s appears before you.", Amonnam(mon));
|
||||
mon->mstrategy &= ~STRAT_APPEARMSG;
|
||||
}
|
||||
@@ -258,18 +254,16 @@ register struct monst *mtmp;
|
||||
newsym(mtmp->mx, mtmp->my);
|
||||
}
|
||||
if (g.youmonst.data->mlet == S_DEMON) { /* Won't blackmail their own. */
|
||||
if (!Deaf)
|
||||
pline("%s says, \"Good hunting, %s.\"", Amonnam(mtmp),
|
||||
flags.female ? "Sister" : "Brother");
|
||||
else if (canseemon(mtmp))
|
||||
pline("%s says something.", Amonnam(mtmp));
|
||||
pline("%s says, \"Good hunting, %s.\"", Amonnam(mtmp),
|
||||
flags.female ? "Sister" : "Brother");
|
||||
if (!tele_restrict(mtmp))
|
||||
(void) rloc(mtmp, TRUE);
|
||||
return 1;
|
||||
}
|
||||
cash = money_cnt(g.invent);
|
||||
demand = (cash * (rnd(80) + 20 * Athome))
|
||||
/ (100 * (1 + (sgn(u.ualign.type) == sgn(mtmp->data->maligntyp))));
|
||||
demand =
|
||||
(cash * (rnd(80) + 20 * Athome))
|
||||
/ (100 * (1 + (sgn(u.ualign.type) == sgn(mtmp->data->maligntyp))));
|
||||
|
||||
if (!demand || g.multi < 0) { /* you have no gold or can't move */
|
||||
mtmp->mpeaceful = 0;
|
||||
@@ -279,22 +273,13 @@ register struct monst *mtmp;
|
||||
/* make sure that the demand is unmeetable if the monster
|
||||
has the Amulet, preventing monster from being satisfied
|
||||
and removed from the game (along with said Amulet...) */
|
||||
/* [actually the Amulet is safe; it would be dropped when
|
||||
mongone() gets rid of the monster; force combat anyway;
|
||||
also make it unmeetable if the player is Deaf, to simplify
|
||||
handling that case as player-won't-pay] */
|
||||
if (mon_has_amulet(mtmp) || Deaf)
|
||||
/* 125: 5*25 in case hero has maximum possible charisma */
|
||||
demand = cash + (long) rn1(1000, 125);
|
||||
if (mon_has_amulet(mtmp))
|
||||
demand = cash + (long) rn1(1000, 40);
|
||||
|
||||
if (!Deaf)
|
||||
pline("%s demands %ld %s for safe passage.",
|
||||
Amonnam(mtmp), demand, currency(demand));
|
||||
else if (canseemon(mtmp))
|
||||
pline("%s seems to be demanding something.", Amonnam(mtmp));
|
||||
pline("%s demands %ld %s for safe passage.", Amonnam(mtmp), demand,
|
||||
currency(demand));
|
||||
|
||||
offer = 0L;
|
||||
if (!Deaf && ((offer = bribe(mtmp)) >= demand)) {
|
||||
if ((offer = bribe(mtmp)) >= demand) {
|
||||
pline("%s vanishes, laughing about cowardly mortals.",
|
||||
Amonnam(mtmp));
|
||||
} else if (offer > 0L
|
||||
@@ -462,18 +447,12 @@ gain_guardian_angel()
|
||||
Hear_again(); /* attempt to cure any deafness now (divine
|
||||
message will be heard even if that fails) */
|
||||
if (Conflict) {
|
||||
if (!Deaf)
|
||||
pline("A voice booms:");
|
||||
else
|
||||
You_feel("a booming voice:");
|
||||
pline("A voice booms:");
|
||||
verbalize("Thy desire for conflict shall be fulfilled!");
|
||||
/* send in some hostile angels instead */
|
||||
lose_guardian_angel((struct monst *) 0);
|
||||
} else if (u.ualign.record > 8) { /* fervent */
|
||||
if (!Deaf)
|
||||
pline("A voice whispers:");
|
||||
else
|
||||
You_feel("a soft voice:");
|
||||
pline("A voice whispers:");
|
||||
verbalize("Thou hast been worthy of me!");
|
||||
mm.x = u.ux;
|
||||
mm.y = u.uy;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 muse.c $NHDT-Date: 1561053256 2019/06/20 17:54:16 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.97 $ */
|
||||
/* NetHack 3.6 muse.c $NHDT-Date: 1560161807 2019/06/10 10:16:47 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.96 $ */
|
||||
/* Copyright (C) 1990 by Ken Arromdee */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -2487,10 +2487,7 @@ boolean by_you; /* true: if mon kills itself, hero gets credit/blame */
|
||||
dmg = 0; /* damage has been applied by explode() */
|
||||
}
|
||||
} else { /* wand/horn of fire w/ positive charge count */
|
||||
if (obj->otyp == FIRE_HORN)
|
||||
mplayhorn(mon, obj, TRUE);
|
||||
else
|
||||
mzapwand(mon, obj, TRUE);
|
||||
mplayhorn(mon, obj, TRUE);
|
||||
/* -1 => monster's wand of fire; 2 => # of damage dice */
|
||||
dmg = zhitm(mon, by_you ? 1 : -1, 2, &odummyp);
|
||||
}
|
||||
|
||||
28
src/objnam.c
28
src/objnam.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 objnam.c $NHDT-Date: 1561081353 2019/06/21 01:42:33 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.244 $ */
|
||||
/* NetHack 3.6 objnam.c $NHDT-Date: 1560185545 2019/06/10 16:52:25 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.243 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2011. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -2812,7 +2812,7 @@ int xtra_prob; /* to force 0% random generation items to also be considered */
|
||||
* probabilities are not very useful because they don't take
|
||||
* the class generation probability into account. [If 10%
|
||||
* of spellbooks were blank and 1% of scrolls were blank,
|
||||
* "blank" would have 10/11 chance to yield a book even though
|
||||
* "blank" would have 10/11 chance to yield a blook even though
|
||||
* scrolls are supposed to be much more common than books.]
|
||||
*/
|
||||
for (i = oclass ? g.bases[(int) oclass] : STRANGE_OBJECT + 1;
|
||||
@@ -3347,7 +3347,6 @@ struct obj *no_wish;
|
||||
for (i = 0; i < (int) (sizeof wrpsym); i++) {
|
||||
register int j = strlen(wrp[i]);
|
||||
|
||||
/* check for "<class> [ of ] something" */
|
||||
if (!strncmpi(bp, wrp[i], j)) {
|
||||
oclass = wrpsym[i];
|
||||
if (oclass != AMULET_CLASS) {
|
||||
@@ -3359,27 +3358,12 @@ struct obj *no_wish;
|
||||
actualn = bp;
|
||||
goto srch;
|
||||
}
|
||||
/* check for "something <class>" */
|
||||
if (!BSTRCMPI(bp, p - j, wrp[i])) {
|
||||
oclass = wrpsym[i];
|
||||
/* for "foo amulet", leave the class name so that
|
||||
wishymatch() can do "of inversion" to try matching
|
||||
"amulet of foo"; other classes don't include their
|
||||
class name in their full object names (where
|
||||
"potion of healing" is just "healing", for instance) */
|
||||
if (oclass != AMULET_CLASS) {
|
||||
p -= j;
|
||||
*p = '\0';
|
||||
if (p > bp && p[-1] == ' ')
|
||||
p[-1] = '\0';
|
||||
} else {
|
||||
/* amulet without "of"; convoluted wording but better a
|
||||
special case that's handled than one that's missing */
|
||||
if (!strncmpi(bp, "versus poison ", 14)) {
|
||||
typ = AMULET_VERSUS_POISON;
|
||||
goto typfnd;
|
||||
}
|
||||
}
|
||||
p -= j;
|
||||
*p = 0;
|
||||
if (p > bp && p[-1] == ' ')
|
||||
p[-1] = 0;
|
||||
actualn = dn = bp;
|
||||
goto srch;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 options.c $NHDT-Date: 1561022792 2019/06/20 09:26:32 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.365 $ */
|
||||
/* NetHack 3.6 options.c $NHDT-Date: 1560789054 2019/06/17 16:30:54 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.364 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Michael Allison, 2008. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -702,23 +702,6 @@ initoptions_init()
|
||||
/* initialize the function pointers for fieldlevel saves */
|
||||
sf_init();
|
||||
|
||||
#if defined(COMPRESS) || defined(ZLIB_COMP)
|
||||
set_savepref("externalcomp");
|
||||
set_restpref("externalcomp");
|
||||
#ifdef RLECOMP
|
||||
set_savepref("!rlecomp");
|
||||
set_restpref("!rlecomp");
|
||||
#endif
|
||||
#else
|
||||
#ifdef ZEROCOMP
|
||||
set_savepref("zerocomp");
|
||||
set_restpref("zerocomp");
|
||||
#endif
|
||||
#ifdef RLECOMP
|
||||
set_savepref("rlecomp");
|
||||
set_restpref("rlecomp");
|
||||
#endif
|
||||
#endif
|
||||
#ifdef SYSFLAGS
|
||||
Strcpy(sysflags.sysflagsid, "sysflags");
|
||||
sysflags.sysflagsid[9] = (char) sizeof (struct sysflag);
|
||||
@@ -738,6 +721,7 @@ initoptions_init()
|
||||
iflags.prevmsg_window = 'r';
|
||||
#endif
|
||||
#endif
|
||||
|
||||
iflags.menu_headings = ATR_INVERSE;
|
||||
iflags.getpos_coords = GPCOORDS_NONE;
|
||||
|
||||
@@ -4253,55 +4237,36 @@ boolean dolist;
|
||||
putstr(win, 0, buf);
|
||||
}
|
||||
} else {
|
||||
const char
|
||||
fmt3[] = " %-12s %-2s %-2s %s",
|
||||
fmt2[] = " %-12s %-2s %-2s",
|
||||
fmt1[] = " %10s %-2s %s",
|
||||
fmt0[] = " %14s %s";
|
||||
|
||||
putstr(win, 0, "");
|
||||
putstr(win, 0, "Selection: On page Full menu");
|
||||
Sprintf(buf, fmt2, "Select all",
|
||||
putstr(win, 0, " Page All items");
|
||||
Sprintf(buf, " Select %s %s",
|
||||
visctrl(get_menu_cmd_key(MENU_SELECT_PAGE)),
|
||||
visctrl(get_menu_cmd_key(MENU_SELECT_ALL)));
|
||||
putstr(win, 0, buf);
|
||||
Sprintf(buf, fmt2, "Deselect all",
|
||||
Sprintf(buf, "Deselect %s %s",
|
||||
visctrl(get_menu_cmd_key(MENU_UNSELECT_PAGE)),
|
||||
visctrl(get_menu_cmd_key(MENU_UNSELECT_ALL)));
|
||||
putstr(win, 0, buf);
|
||||
Sprintf(buf, fmt2, "Invert all",
|
||||
Sprintf(buf, " Invert %s %s",
|
||||
visctrl(get_menu_cmd_key(MENU_INVERT_PAGE)),
|
||||
visctrl(get_menu_cmd_key(MENU_INVERT_ALL)));
|
||||
putstr(win, 0, buf);
|
||||
Sprintf(buf, fmt3, "Text match", "",
|
||||
visctrl(get_menu_cmd_key(MENU_SEARCH)),
|
||||
"Search and toggle matching entries");
|
||||
putstr(win, 0, "");
|
||||
Sprintf(buf, " Go to %s Next page",
|
||||
visctrl(get_menu_cmd_key(MENU_NEXT_PAGE)));
|
||||
putstr(win, 0, buf);
|
||||
Sprintf(buf, " %s Previous page",
|
||||
visctrl(get_menu_cmd_key(MENU_PREVIOUS_PAGE)));
|
||||
putstr(win, 0, buf);
|
||||
Sprintf(buf, " %s First page",
|
||||
visctrl(get_menu_cmd_key(MENU_FIRST_PAGE)));
|
||||
putstr(win, 0, buf);
|
||||
Sprintf(buf, " %s Last page",
|
||||
visctrl(get_menu_cmd_key(MENU_LAST_PAGE)));
|
||||
putstr(win, 0, buf);
|
||||
putstr(win, 0, "");
|
||||
putstr(win, 0, "Navigation:");
|
||||
Sprintf(buf, fmt1, "Go to ",
|
||||
visctrl(get_menu_cmd_key(MENU_NEXT_PAGE)),
|
||||
"Next page");
|
||||
putstr(win, 0, buf);
|
||||
Sprintf(buf, fmt1, "",
|
||||
visctrl(get_menu_cmd_key(MENU_PREVIOUS_PAGE)),
|
||||
"Previous page");
|
||||
putstr(win, 0, buf);
|
||||
Sprintf(buf, fmt1, "",
|
||||
visctrl(get_menu_cmd_key(MENU_FIRST_PAGE)),
|
||||
"First page");
|
||||
putstr(win, 0, buf);
|
||||
Sprintf(buf, fmt1, "",
|
||||
visctrl(get_menu_cmd_key(MENU_LAST_PAGE)),
|
||||
"Last page");
|
||||
putstr(win, 0, buf);
|
||||
Sprintf(buf, fmt0, "SPACE", "Next page, if any, otherwise RETURN");
|
||||
putstr(win, 0, buf);
|
||||
Sprintf(buf, fmt0, "RETURN/ENTER",
|
||||
"Finish menu with any selection(s) made");
|
||||
putstr(win, 0, buf);
|
||||
Sprintf(buf, fmt0, "ESCAPE",
|
||||
"Cancel menu without selecting anything");
|
||||
Sprintf(buf, " %s Search and toggle matching entries",
|
||||
visctrl(get_menu_cmd_key(MENU_SEARCH)));
|
||||
putstr(win, 0, buf);
|
||||
}
|
||||
}
|
||||
|
||||
13
src/pray.c
13
src/pray.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 pray.c $NHDT-Date: 1561061321 2019/06/20 20:08:41 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.115 $ */
|
||||
/* NetHack 3.6 pray.c $NHDT-Date: 1559853037 2019/06/06 20:30:37 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.114 $ */
|
||||
/* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -484,7 +484,7 @@ int trouble;
|
||||
what = rightglow;
|
||||
else if (otmp == uleft)
|
||||
what = leftglow;
|
||||
decurse:
|
||||
decurse:
|
||||
if (!otmp) {
|
||||
impossible("fix_worst_trouble: nothing to uncurse.");
|
||||
return;
|
||||
@@ -716,9 +716,8 @@ aligntyp resp_god;
|
||||
(on_altar() && (a_align(u.ux, u.uy) != resp_god))
|
||||
? "scorn"
|
||||
: "call upon");
|
||||
/* [why isn't this using verbalize()?] */
|
||||
pline("\"Then die, %s!\"",
|
||||
(g.youmonst.data->mlet == S_HUMAN) ? "mortal" : "creature");
|
||||
g.youmonst.data->mlet == S_HUMAN ? "mortal" : "creature");
|
||||
summon_minion(resp_god, FALSE);
|
||||
break;
|
||||
|
||||
@@ -798,7 +797,7 @@ gcrownu()
|
||||
&& uwep->oartifact != ART_STORMBRINGER))
|
||||
&& !carrying(SPE_FINGER_OF_DEATH)) {
|
||||
class_gift = SPE_FINGER_OF_DEATH;
|
||||
make_splbk:
|
||||
make_splbk:
|
||||
obj = mksobj(class_gift, TRUE, FALSE);
|
||||
bless(obj);
|
||||
obj->bknown = 1; /* ok to skip set_bknown() */
|
||||
@@ -1484,7 +1483,7 @@ dosacrifice()
|
||||
|
||||
if (otmp->otyp == AMULET_OF_YENDOR) {
|
||||
if (!highaltar) {
|
||||
too_soon:
|
||||
too_soon:
|
||||
if (altaralign == A_NONE && Inhell)
|
||||
/* hero has left Moloch's Sanctum so is in the process
|
||||
of getting away with the Amulet (outside of Gehennom,
|
||||
@@ -1580,7 +1579,7 @@ dosacrifice()
|
||||
}
|
||||
|
||||
if (altaralign != u.ualign.type && highaltar) {
|
||||
desecrate_high_altar:
|
||||
desecrate_high_altar:
|
||||
/*
|
||||
* REAL BAD NEWS!!! High altars cannot be converted. Even an attempt
|
||||
* gets the god who owns it truly pissed off.
|
||||
|
||||
276
src/restore.c
276
src/restore.c
@@ -25,9 +25,6 @@ STATIC_DCL void FDECL(zerocomp_mread, (int, genericptr_t, unsigned int));
|
||||
STATIC_DCL int NDECL(zerocomp_mgetc);
|
||||
#endif
|
||||
|
||||
STATIC_DCL void NDECL(def_minit);
|
||||
STATIC_DCL void FDECL(def_mread, (int, genericptr_t, unsigned int));
|
||||
|
||||
STATIC_DCL void NDECL(find_lev_obj);
|
||||
STATIC_DCL void FDECL(restlevchn, (NHFILE *));
|
||||
STATIC_DCL void FDECL(restdamage, (NHFILE *, BOOLEAN_P));
|
||||
@@ -45,27 +42,6 @@ STATIC_OVL void FDECL(restore_msghistory, (NHFILE *));
|
||||
STATIC_DCL void FDECL(reset_oattached_mids, (BOOLEAN_P));
|
||||
STATIC_DCL void FDECL(rest_levl, (NHFILE *, BOOLEAN_P));
|
||||
|
||||
#if 0
|
||||
extern int FDECL(nhin, (NHFILE *,char *,int,const char *, genericptr_t,int));
|
||||
int FDECL(dorecover, (NHFILE *));
|
||||
extern char *FDECL(sfdt2txt,(int));
|
||||
extern size_t FDECL(sfdtsz,(int));
|
||||
#endif
|
||||
|
||||
static struct restore_procs restoreprocs = {
|
||||
#if !defined(ZEROCOMP) || (defined(COMPRESS) || defined(ZLIB_COMP))
|
||||
"externalcomp", 0,
|
||||
def_minit,
|
||||
def_mread,
|
||||
def_bclose,
|
||||
#else
|
||||
"zerocomp", 0,
|
||||
zerocomp_minit,
|
||||
zerocomp_mread,
|
||||
zerocomp_bclose,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* Save a mapping of IDs from ghost levels to the current level. This
|
||||
* map is used by the timer routines when restoring ghost levels.
|
||||
@@ -993,6 +969,7 @@ xchar ltmp;
|
||||
pline("Be seeing you...");
|
||||
nh_terminate(EXIT_SUCCESS);
|
||||
}
|
||||
nnhfp->mode = savemode;
|
||||
#endif /* MFLOPPY */
|
||||
bufon(nnhfp->fd);
|
||||
nnhfp->mode = WRITING | FREEING;
|
||||
@@ -1067,11 +1044,11 @@ NHFILE *nhfp;
|
||||
if (!WINDOWPORT("X11"))
|
||||
putstr(WIN_MAP, 0, "Restoring:");
|
||||
#endif
|
||||
restoreprocs.mread_flags = 1; /* return despite error */
|
||||
restoreinfo.mread_flags = 1; /* return despite error */
|
||||
while (1) {
|
||||
if (nhfp->structlevel) {
|
||||
mread(nhfp->fd, (genericptr_t) <mp, sizeof ltmp);
|
||||
if (restoreprocs.mread_flags == -1)
|
||||
if (restoreinfo.mread_flags == -1)
|
||||
break;
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
@@ -1095,7 +1072,7 @@ NHFILE *nhfp;
|
||||
if (rtmp < 2)
|
||||
return rtmp; /* dorecover called recursively */
|
||||
}
|
||||
restoreprocs.mread_flags = 0;
|
||||
restoreinfo.mread_flags = 0;
|
||||
if (nhfp->fieldlevel && nhfp->addinfo)
|
||||
sfi_addinfo(nhfp, "NetHack", "end", "savefile", 0);
|
||||
|
||||
@@ -1105,11 +1082,6 @@ NHFILE *nhfp;
|
||||
|
||||
getlev(nhfp, 0, (xchar) 0, FALSE);
|
||||
close_nhfile(nhfp);
|
||||
/* Now set the restore settings to match the
|
||||
* settings used by the save file output routines
|
||||
*/
|
||||
reset_restpref();
|
||||
|
||||
restlevelstate(stuckid, steedid);
|
||||
g.program_state.something_worth_saving = 1; /* useful data now exists */
|
||||
|
||||
@@ -1500,18 +1472,8 @@ char *plbuf;
|
||||
(void) read(nhfp->fd, (genericptr_t) plbuf, pltmpsiz);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
#if 0
|
||||
if ((nhfp->mode & WRITING) != 0) {
|
||||
#endif
|
||||
sfi_int(nhfp, &pltmpsiz, "plname", "plname_size", 1);
|
||||
sfi_str(nhfp, plbuf, "plname", "g.plname", pltmpsiz);
|
||||
#if 0
|
||||
} else {
|
||||
/* int rlen; */
|
||||
(void) read(nhfp->fd, (genericptr_t) &pltmpsiz, sizeof(pltmpsiz));
|
||||
(void) read(nhfp->fd, (genericptr_t) plbuf, pltmpsiz);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1709,41 +1671,6 @@ winid bannerwin; /* if not WIN_ERR, clear window and show copyright in menu */
|
||||
}
|
||||
#endif /* SELECTSAVED */
|
||||
|
||||
void
|
||||
minit()
|
||||
{
|
||||
(*restoreprocs.restore_minit)();
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
mread(fd, buf, len)
|
||||
register int fd;
|
||||
register genericptr_t buf;
|
||||
register unsigned int len;
|
||||
{
|
||||
|
||||
#ifdef TROUBLESHOOTING
|
||||
int n;
|
||||
static int mcatch;
|
||||
n = mcatch;
|
||||
again:
|
||||
mcatch=rn2(500);
|
||||
if (mcatch == n) goto again;
|
||||
#endif
|
||||
|
||||
(*restoreprocs.restore_mread)(fd, buf, len);
|
||||
return;
|
||||
}
|
||||
|
||||
/* examine the version info and the savefile_info data
|
||||
that immediately follows it.
|
||||
Return 0 if it passed the checks.
|
||||
Return 1 if it failed the version check.
|
||||
Return 2 if it failed the savefile feature check.
|
||||
Return -1 if it failed for some unknown reason.
|
||||
*/
|
||||
|
||||
int
|
||||
validate(nhfp, name)
|
||||
NHFILE *nhfp;
|
||||
@@ -1751,7 +1678,7 @@ const char *name;
|
||||
{
|
||||
int rlen;
|
||||
struct savefile_info sfi;
|
||||
unsigned long compatible, utdflags = 0L;
|
||||
unsigned long utdflags = 0L;
|
||||
boolean verbose = name ? TRUE : FALSE, reslt = FALSE;
|
||||
|
||||
if (nhfp->structlevel)
|
||||
@@ -1780,200 +1707,7 @@ const char *name;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if ((utdflags & UTD_SKIP_SAVEFILEINFO) != 0)
|
||||
return 0;
|
||||
|
||||
compatible = (sfi.sfi1 & sfcap.sfi1);
|
||||
if ((sfi.sfi1 & SFI1_ZEROCOMP) == SFI1_ZEROCOMP) {
|
||||
if ((compatible & SFI1_ZEROCOMP) != SFI1_ZEROCOMP) {
|
||||
if (verbose) {
|
||||
pline("File \"%s\" has incompatible ZEROCOMP compression.", name);
|
||||
wait_synch();
|
||||
}
|
||||
return 2;
|
||||
} else if ((sfrestinfo.sfi1 & SFI1_ZEROCOMP) != SFI1_ZEROCOMP) {
|
||||
set_restpref("zerocomp");
|
||||
}
|
||||
}
|
||||
|
||||
if ((sfi.sfi1 & SFI1_EXTERNALCOMP) == SFI1_EXTERNALCOMP) {
|
||||
if ((compatible & SFI1_EXTERNALCOMP) != SFI1_EXTERNALCOMP) {
|
||||
if (verbose) {
|
||||
pline("File \"%s\" lacks required internal compression.", name);
|
||||
wait_synch();
|
||||
}
|
||||
return 2;
|
||||
} else if ((sfrestinfo.sfi1 & SFI1_EXTERNALCOMP) != SFI1_EXTERNALCOMP) {
|
||||
set_restpref("externalcomp");
|
||||
}
|
||||
}
|
||||
|
||||
/* RLECOMP check must be last, after ZEROCOMP or INTERNALCOMP adjustments */
|
||||
if ((sfi.sfi1 & SFI1_RLECOMP) == SFI1_RLECOMP) {
|
||||
if ((compatible & SFI1_RLECOMP) != SFI1_RLECOMP) {
|
||||
if (verbose) {
|
||||
pline("File \"%s\" has incompatible run-length compression.", name);
|
||||
wait_synch();
|
||||
}
|
||||
return 2;
|
||||
} else if ((sfrestinfo.sfi1 & SFI1_RLECOMP) != SFI1_RLECOMP) {
|
||||
set_restpref("rlecomp");
|
||||
}
|
||||
}
|
||||
/* savefile does not have RLECOMP level location compression, so adjust */
|
||||
else
|
||||
set_restpref("!rlecomp");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
reset_restpref()
|
||||
{
|
||||
#ifdef ZEROCOMP
|
||||
if (iflags.zerocomp)
|
||||
set_restpref("zerocomp");
|
||||
else
|
||||
#endif
|
||||
set_restpref("externalcomp");
|
||||
#ifdef RLECOMP
|
||||
if (iflags.rlecomp)
|
||||
set_restpref("rlecomp");
|
||||
else
|
||||
#endif
|
||||
set_restpref("!rlecomp");
|
||||
}
|
||||
|
||||
void
|
||||
set_restpref(suitename)
|
||||
const char *suitename;
|
||||
{
|
||||
if (!strcmpi(suitename, "externalcomp")) {
|
||||
restoreprocs.name = "externalcomp";
|
||||
restoreprocs.restore_mread = def_mread;
|
||||
restoreprocs.restore_minit = def_minit;
|
||||
sfrestinfo.sfi1 |= SFI1_EXTERNALCOMP;
|
||||
sfrestinfo.sfi1 &= ~SFI1_ZEROCOMP;
|
||||
def_minit();
|
||||
}
|
||||
if (!strcmpi(suitename, "!rlecomp")) {
|
||||
sfrestinfo.sfi1 &= ~SFI1_RLECOMP;
|
||||
}
|
||||
#ifdef ZEROCOMP
|
||||
if (!strcmpi(suitename, "zerocomp")) {
|
||||
restoreprocs.name = "zerocomp";
|
||||
restoreprocs.restore_mread = zerocomp_mread;
|
||||
restoreprocs.restore_minit = zerocomp_minit;
|
||||
sfrestinfo.sfi1 |= SFI1_ZEROCOMP;
|
||||
sfrestinfo.sfi1 &= ~SFI1_EXTERNALCOMP;
|
||||
zerocomp_minit();
|
||||
}
|
||||
#endif
|
||||
#ifdef RLECOMP
|
||||
if (!strcmpi(suitename, "rlecomp")) {
|
||||
sfrestinfo.sfi1 |= SFI1_RLECOMP;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ZEROCOMP
|
||||
#define RLESC '\0' /* Leading character for run of RLESC's */
|
||||
|
||||
#ifndef ZEROCOMP_BUFSIZ
|
||||
#define ZEROCOMP_BUFSIZ BUFSZ
|
||||
#endif
|
||||
static NEARDATA unsigned char inbuf[ZEROCOMP_BUFSIZ];
|
||||
static NEARDATA unsigned short inbufp = 0;
|
||||
static NEARDATA unsigned short inbufsz = 0;
|
||||
static NEARDATA short inrunlength = -1;
|
||||
static NEARDATA int mreadfd;
|
||||
|
||||
STATIC_OVL int
|
||||
zerocomp_mgetc()
|
||||
{
|
||||
if (inbufp >= inbufsz) {
|
||||
inbufsz = read(mreadfd, (genericptr_t)inbuf, sizeof inbuf);
|
||||
if (!inbufsz) {
|
||||
if (inbufp > sizeof inbuf)
|
||||
error("EOF on file #%d.\n", mreadfd);
|
||||
inbufp = 1 + sizeof inbuf; /* exactly one warning :-) */
|
||||
return -1;
|
||||
}
|
||||
inbufp = 0;
|
||||
}
|
||||
return inbuf[inbufp++];
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
zerocomp_minit()
|
||||
{
|
||||
inbufsz = 0;
|
||||
inbufp = 0;
|
||||
inrunlength = -1;
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
zerocomp_mread(fd, buf, len)
|
||||
int fd;
|
||||
genericptr_t buf;
|
||||
register unsigned len;
|
||||
{
|
||||
/*register int readlen = 0;*/
|
||||
if (fd < 0) error("Restore error; mread attempting to read file %d.", fd);
|
||||
mreadfd = fd;
|
||||
while (len--) {
|
||||
if (inrunlength > 0) {
|
||||
inrunlength--;
|
||||
*(*((char **)&buf))++ = '\0';
|
||||
} else {
|
||||
register short ch = zerocomp_mgetc();
|
||||
if (ch < 0) {
|
||||
restoreprocs.mread_flags = -1;
|
||||
return;
|
||||
}
|
||||
if ((*(*(char **)&buf)++ = (char)ch) == RLESC) {
|
||||
inrunlength = zerocomp_mgetc();
|
||||
}
|
||||
}
|
||||
/*readlen++;*/
|
||||
}
|
||||
}
|
||||
#endif /* ZEROCOMP */
|
||||
|
||||
STATIC_OVL void
|
||||
def_minit()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
def_mread(fd, buf, len)
|
||||
register int fd;
|
||||
register genericptr_t buf;
|
||||
register unsigned int len;
|
||||
{
|
||||
register int rlen;
|
||||
#if defined(BSD) || defined(ULTRIX)
|
||||
#define readLenType int
|
||||
#else /* e.g. SYSV, __TURBOC__ */
|
||||
#define readLenType unsigned
|
||||
#endif
|
||||
|
||||
rlen = read(fd, buf, (readLenType) len);
|
||||
if ((readLenType) rlen != (readLenType) len) {
|
||||
if (restoreprocs.mread_flags == 1) { /* means "return anyway" */
|
||||
restoreprocs.mread_flags = -1;
|
||||
return;
|
||||
} else {
|
||||
pline("Read %d instead of %u bytes.", rlen, len);
|
||||
if (g.restoring) {
|
||||
(void) nhclose(fd);
|
||||
(void) delete_savefile();
|
||||
error("Error restoring old game.");
|
||||
}
|
||||
panic("Error reading level file.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*restore.c*/
|
||||
|
||||
429
src/save.c
429
src/save.c
@@ -20,6 +20,10 @@ long bytes_counted;
|
||||
static int count_only;
|
||||
#endif
|
||||
|
||||
#if defined(UNIX) || defined(WIN32)
|
||||
#define USE_BUFFERING
|
||||
#endif
|
||||
|
||||
/*SAVE2018*/
|
||||
extern void FDECL(nhout, (int, const char *,
|
||||
const char *, int, genericptr_t, int));
|
||||
@@ -48,11 +52,7 @@ STATIC_DCL void FDECL(savelev0, (NHFILE *, XCHAR_P, int));
|
||||
STATIC_DCL boolean NDECL(swapout_oldest);
|
||||
STATIC_DCL void FDECL(copyfile, (char *, char *));
|
||||
#endif /* MFLOPPY */
|
||||
/* STATIC_DCL void FDECL(savelevl, (int fd, BOOLEAN_P)); */
|
||||
STATIC_DCL void FDECL(def_bufon, (int));
|
||||
STATIC_DCL void FDECL(def_bufoff, (int));
|
||||
STATIC_DCL void FDECL(def_bflush, (int));
|
||||
STATIC_DCL void FDECL(def_bwrite, (int, genericptr_t, unsigned int));
|
||||
|
||||
#ifdef ZEROCOMP
|
||||
STATIC_DCL void FDECL(zerocomp_bufon, (int));
|
||||
STATIC_DCL void FDECL(zerocomp_bufoff, (int));
|
||||
@@ -61,22 +61,6 @@ STATIC_DCL void FDECL(zerocomp_bwrite, (int, genericptr_t, unsigned int));
|
||||
STATIC_DCL void FDECL(zerocomp_bputc, (int));
|
||||
#endif
|
||||
|
||||
static struct save_procs {
|
||||
const char *name;
|
||||
void FDECL((*save_bufon), (int));
|
||||
void FDECL((*save_bufoff), (int));
|
||||
void FDECL((*save_bflush), (int));
|
||||
void FDECL((*save_bwrite), (int, genericptr_t, unsigned int));
|
||||
void FDECL((*save_bclose), (int));
|
||||
} saveprocs = {
|
||||
#if !defined(ZEROCOMP) || (defined(COMPRESS) || defined(ZLIB_COMP))
|
||||
"externalcomp", def_bufon, def_bufoff, def_bflush, def_bwrite, def_bclose,
|
||||
#else
|
||||
"zerocomp", zerocomp_bufon, zerocomp_bufoff,
|
||||
zerocomp_bflush, zerocomp_bwrite, zerocomp_bclose,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(UNIX) || defined(VMS) || defined(__EMX__) || defined(WIN32)
|
||||
#define HUP if (!g.program_state.done_hup)
|
||||
#else
|
||||
@@ -118,9 +102,8 @@ dosave0()
|
||||
const char *fq_save;
|
||||
xchar ltmp;
|
||||
d_level uz_save;
|
||||
char whynot[BUFSZ], indicate;
|
||||
char whynot[BUFSZ];
|
||||
NHFILE *nhfp, *onhfp;
|
||||
int cmc = 0;
|
||||
|
||||
/* we may get here via hangup signal, in which case we want to fix up
|
||||
a few of things before saving so that they won't be restored in
|
||||
@@ -228,23 +211,6 @@ dosave0()
|
||||
sfo_addinfo(nhfp, "NetHack", "start", "savefile", 0);
|
||||
|
||||
nhfp->mode = WRITING | FREEING;
|
||||
if (nhfp->mode & WRITING) {
|
||||
if (nhfp->fieldlevel && nhfp->mode & WRITING) {
|
||||
indicate = (nhfp->fnidx == lendian) ? 'l'
|
||||
: (nhfp->fnidx == ascii) ? 'a' : 'u';
|
||||
sfo_char(nhfp, &indicate, "indicate", "format", 1);
|
||||
cmc = critical_members_count();
|
||||
{
|
||||
pline("critical-members=%d.", cmc);
|
||||
}
|
||||
sfo_int(nhfp, &cmc, "validate", "critical_members_count", 1);
|
||||
}
|
||||
if (nhfp->structlevel && nhfp->mode & WRITING) {
|
||||
indicate = 'h'; /* historical */
|
||||
bwrite(nhfp->fd, (genericptr_t) &indicate, sizeof indicate);
|
||||
bwrite(nhfp->fd, (genericptr_t) &cmc, sizeof cmc);
|
||||
}
|
||||
}
|
||||
store_version(nhfp);
|
||||
store_savefileinfo(nhfp);
|
||||
if (nhfp && nhfp->fplog)
|
||||
@@ -788,320 +754,6 @@ boolean rlecomp;
|
||||
}
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
bufon(fd)
|
||||
int fd;
|
||||
{
|
||||
(*saveprocs.save_bufon)(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
bufoff(fd)
|
||||
int fd;
|
||||
{
|
||||
(*saveprocs.save_bufoff)(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* flush run and buffer */
|
||||
void
|
||||
bflush(fd)
|
||||
register int fd;
|
||||
{
|
||||
(*saveprocs.save_bflush)(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
bwrite(fd, loc, num)
|
||||
int fd;
|
||||
genericptr_t loc;
|
||||
register unsigned num;
|
||||
{
|
||||
(*saveprocs.save_bwrite)(fd, loc, num);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
bclose(fd)
|
||||
int fd;
|
||||
{
|
||||
(*saveprocs.save_bclose)(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
static int bw_fd = -1;
|
||||
static FILE *bw_FILE = 0;
|
||||
static boolean buffering = FALSE;
|
||||
|
||||
STATIC_OVL void
|
||||
def_bufon(fd)
|
||||
int fd;
|
||||
{
|
||||
#ifdef UNIX
|
||||
if(bw_fd != fd) {
|
||||
if(bw_fd >= 0)
|
||||
panic("double buffering unexpected");
|
||||
bw_fd = fd;
|
||||
if((bw_FILE = fdopen(fd, "w")) == 0)
|
||||
panic("buffering of file %d failed", fd);
|
||||
}
|
||||
#endif
|
||||
buffering = TRUE;
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
def_bufoff(fd)
|
||||
int fd;
|
||||
{
|
||||
def_bflush(fd);
|
||||
buffering = FALSE;
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
def_bflush(fd)
|
||||
int fd;
|
||||
{
|
||||
#ifdef UNIX
|
||||
if (fd == bw_fd) {
|
||||
if (fflush(bw_FILE) == EOF)
|
||||
panic("flush of savefile failed!");
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
def_bwrite(fd, loc, num)
|
||||
register int fd;
|
||||
register genericptr_t loc;
|
||||
register unsigned num;
|
||||
{
|
||||
boolean failed;
|
||||
|
||||
#ifdef MFLOPPY
|
||||
bytes_counted += num;
|
||||
if (count_only)
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifdef UNIX
|
||||
if (buffering) {
|
||||
if (fd != bw_fd)
|
||||
panic("unbuffered write to fd %d (!= %d)", fd, bw_fd);
|
||||
|
||||
failed = (fwrite(loc, (int) num, 1, bw_FILE) != 1);
|
||||
} else
|
||||
#endif /* UNIX */
|
||||
{
|
||||
/* lint wants 3rd arg of write to be an int; lint -p an unsigned */
|
||||
#if defined(BSD) || defined(ULTRIX) || defined(WIN32) || defined(_MSC_VER)
|
||||
failed = ((long) write(fd, loc, (int) num) != (long) num);
|
||||
#else /* e.g. SYSV, __TURBOC__ */
|
||||
failed = ((long) write(fd, loc, num) != (long) num);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
#if defined(UNIX) || defined(VMS) || defined(__EMX__)
|
||||
if (g.program_state.done_hup)
|
||||
nh_terminate(EXIT_FAILURE);
|
||||
else
|
||||
#endif
|
||||
panic("cannot write %u bytes to file #%d", num, fd);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
def_bclose(fd)
|
||||
int fd;
|
||||
{
|
||||
bufoff(fd);
|
||||
#ifdef UNIX
|
||||
if (fd == bw_fd) {
|
||||
(void) fclose(bw_FILE);
|
||||
bw_fd = -1;
|
||||
bw_FILE = 0;
|
||||
} else
|
||||
#endif
|
||||
(void) nhclose(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ZEROCOMP
|
||||
/* The runs of zero-run compression are flushed after the game state or a
|
||||
* level is written out. This adds a couple bytes to a save file, where
|
||||
* the runs could be mashed together, but it allows gluing together game
|
||||
* state and level files to form a save file, and it means the flushing
|
||||
* does not need to be specifically called for every other time a level
|
||||
* file is written out.
|
||||
*/
|
||||
|
||||
#define RLESC '\0' /* Leading character for run of LRESC's */
|
||||
#define flushoutrun(ln) (zerocomp_bputc(RLESC), zerocomp_bputc(ln), ln = -1)
|
||||
|
||||
#ifndef ZEROCOMP_BUFSIZ
|
||||
# define ZEROCOMP_BUFSIZ BUFSZ
|
||||
#endif
|
||||
static NEARDATA unsigned char outbuf[ZEROCOMP_BUFSIZ];
|
||||
static NEARDATA unsigned short outbufp = 0;
|
||||
static NEARDATA short outrunlength = -1;
|
||||
static NEARDATA int bwritefd;
|
||||
static NEARDATA boolean compressing = FALSE;
|
||||
|
||||
/*dbg()
|
||||
{
|
||||
HUP printf("outbufp %d outrunlength %d\n", outbufp,outrunlength);
|
||||
}*/
|
||||
|
||||
STATIC_OVL void
|
||||
zerocomp_bputc(c)
|
||||
int c;
|
||||
{
|
||||
#ifdef MFLOPPY
|
||||
bytes_counted++;
|
||||
if (count_only)
|
||||
return;
|
||||
#endif
|
||||
if (outbufp >= sizeof outbuf) {
|
||||
(void) write(bwritefd, outbuf, sizeof outbuf);
|
||||
outbufp = 0;
|
||||
}
|
||||
outbuf[outbufp++] = (unsigned char)c;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
STATIC_OVL zerocomp_bufon(fd)
|
||||
int fd;
|
||||
{
|
||||
compressing = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
STATIC_OVL void
|
||||
zerocomp_bufoff(fd)
|
||||
int fd;
|
||||
{
|
||||
if (outbufp) {
|
||||
outbufp = 0;
|
||||
panic("closing file with buffered data still unwritten");
|
||||
}
|
||||
outrunlength = -1;
|
||||
compressing = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* flush run and buffer */
|
||||
STATIC_OVL void
|
||||
zerocomp_bflush(fd)
|
||||
register int fd;
|
||||
{
|
||||
bwritefd = fd;
|
||||
if (outrunlength >= 0) { /* flush run */
|
||||
flushoutrun(outrunlength);
|
||||
}
|
||||
#ifdef MFLOPPY
|
||||
if (count_only)
|
||||
outbufp = 0;
|
||||
#endif
|
||||
|
||||
if (outbufp) {
|
||||
if (write(fd, outbuf, outbufp) != outbufp) {
|
||||
#if defined(UNIX) || defined(VMS) || defined(__EMX__)
|
||||
if (g.program_state.done_hup)
|
||||
nh_terminate(EXIT_FAILURE);
|
||||
else
|
||||
#endif
|
||||
zerocomp_bclose(fd); /* panic (outbufp != 0) */
|
||||
}
|
||||
outbufp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
zerocomp_bwrite(fd, loc, num)
|
||||
int fd;
|
||||
genericptr_t loc;
|
||||
register unsigned num;
|
||||
{
|
||||
register unsigned char *bp = (unsigned char *) loc;
|
||||
|
||||
if (!compressing) {
|
||||
#ifdef MFLOPPY
|
||||
bytes_counted += num;
|
||||
if (count_only)
|
||||
return;
|
||||
#endif
|
||||
if ((unsigned) write(fd, loc, num) != num) {
|
||||
#if defined(UNIX) || defined(VMS) || defined(__EMX__)
|
||||
if (g.program_state.done_hup)
|
||||
nh_terminate(EXIT_FAILURE);
|
||||
else
|
||||
#endif
|
||||
panic("cannot write %u bytes to file #%d", num, fd);
|
||||
}
|
||||
} else {
|
||||
bwritefd = fd;
|
||||
for (; num; num--, bp++) {
|
||||
if (*bp == RLESC) { /* One more char in run */
|
||||
if (++outrunlength == 0xFF) {
|
||||
flushoutrun(outrunlength);
|
||||
}
|
||||
} else { /* end of run */
|
||||
if (outrunlength >= 0) { /* flush run */
|
||||
flushoutrun(outrunlength);
|
||||
}
|
||||
zerocomp_bputc(*bp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
zerocomp_bclose(fd)
|
||||
int fd;
|
||||
{
|
||||
zerocomp_bufoff(fd);
|
||||
(void) nhclose(fd);
|
||||
return;
|
||||
}
|
||||
#endif /* ZEROCOMP */
|
||||
|
||||
STATIC_OVL void
|
||||
savelevchn(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
s_level *tmplev, *tmplev2;
|
||||
int cnt = 0;
|
||||
|
||||
for (tmplev = g.sp_levchn; tmplev; tmplev = tmplev->next)
|
||||
cnt++;
|
||||
if (perform_bwrite(nhfp)) {
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) &cnt, sizeof cnt);
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_int(nhfp, &cnt, "levchn", "lev_count", 1);
|
||||
}
|
||||
for (tmplev = g.sp_levchn; tmplev; tmplev = tmplev2) {
|
||||
tmplev2 = tmplev->next;
|
||||
if (perform_bwrite(nhfp)) {
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) tmplev, sizeof *tmplev);
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_s_level(nhfp, tmplev, "levchn", "s_level", 1);
|
||||
}
|
||||
if (release_data(nhfp))
|
||||
free((genericptr_t) tmplev);
|
||||
}
|
||||
if (release_data(nhfp))
|
||||
g.sp_levchn = 0;
|
||||
}
|
||||
|
||||
/* used when saving a level and also when saving dungeon overview data */
|
||||
void
|
||||
savecemetery(nhfp, cemeteryaddr)
|
||||
@@ -1487,6 +1139,38 @@ NHFILE *nhfp;
|
||||
g.ffruit = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
STATIC_OVL void
|
||||
savelevchn(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
s_level *tmplev, *tmplev2;
|
||||
int cnt = 0;
|
||||
|
||||
for (tmplev = g.sp_levchn; tmplev; tmplev = tmplev->next)
|
||||
cnt++;
|
||||
if (perform_bwrite(nhfp)) {
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) &cnt, sizeof cnt);
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_int(nhfp, &cnt, "levchn", "lev_count", 1);
|
||||
}
|
||||
for (tmplev = g.sp_levchn; tmplev; tmplev = tmplev2) {
|
||||
tmplev2 = tmplev->next;
|
||||
if (perform_bwrite(nhfp)) {
|
||||
if (nhfp->structlevel)
|
||||
bwrite(nhfp->fd, (genericptr_t) tmplev, sizeof *tmplev);
|
||||
if (nhfp->fieldlevel)
|
||||
sfo_s_level(nhfp, tmplev, "levchn", "s_level", 1);
|
||||
}
|
||||
if (release_data(nhfp))
|
||||
free((genericptr_t) tmplev);
|
||||
}
|
||||
if (release_data(nhfp))
|
||||
g.sp_levchn = 0;
|
||||
}
|
||||
|
||||
void
|
||||
store_plname_in_file(nhfp)
|
||||
NHFILE *nhfp;
|
||||
@@ -1573,42 +1257,6 @@ NHFILE *nhfp;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
set_savepref(suitename)
|
||||
const char *suitename;
|
||||
{
|
||||
if (!strcmpi(suitename, "externalcomp")) {
|
||||
saveprocs.name = "externalcomp";
|
||||
saveprocs.save_bufon = def_bufon;
|
||||
saveprocs.save_bufoff = def_bufoff;
|
||||
saveprocs.save_bflush = def_bflush;
|
||||
saveprocs.save_bwrite = def_bwrite;
|
||||
saveprocs.save_bclose = def_bclose;
|
||||
sfsaveinfo.sfi1 |= SFI1_EXTERNALCOMP;
|
||||
sfsaveinfo.sfi1 &= ~SFI1_ZEROCOMP;
|
||||
}
|
||||
if (!strcmpi(suitename, "!rlecomp")) {
|
||||
sfsaveinfo.sfi1 &= ~SFI1_RLECOMP;
|
||||
}
|
||||
#ifdef ZEROCOMP
|
||||
if (!strcmpi(suitename, "zerocomp")) {
|
||||
saveprocs.name = "zerocomp";
|
||||
saveprocs.save_bufon = zerocomp_bufon;
|
||||
saveprocs.save_bufoff = zerocomp_bufoff;
|
||||
saveprocs.save_bflush = zerocomp_bflush;
|
||||
saveprocs.save_bwrite = zerocomp_bwrite;
|
||||
saveprocs.save_bclose = zerocomp_bclose;
|
||||
sfsaveinfo.sfi1 |= SFI1_ZEROCOMP;
|
||||
sfsaveinfo.sfi1 &= ~SFI1_EXTERNALCOMP;
|
||||
}
|
||||
#endif
|
||||
#ifdef RLECOMP
|
||||
if (!strcmpi(suitename, "rlecomp")) {
|
||||
sfsaveinfo.sfi1 |= SFI1_RLECOMP;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* also called by prscore(); this probably belongs in dungeon.c... */
|
||||
void
|
||||
free_dungeons()
|
||||
@@ -1800,5 +1448,4 @@ co_false()
|
||||
}
|
||||
|
||||
#endif /* MFLOPPY */
|
||||
|
||||
/*save.c*/
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
#include "wintype.h"
|
||||
#include "sfproto.h"
|
||||
|
||||
#define BUILD_DATE "Sat Jun 22 23:55:47 2019"
|
||||
#define BUILD_TIME (1561262147L)
|
||||
#define BUILD_DATE "Sat Jun 22 22:53:12 2019"
|
||||
#define BUILD_TIME (1561258392L)
|
||||
|
||||
#define NHTYPE_SIMPLE 1
|
||||
#define NHTYPE_COMPLEX 2
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
#endif
|
||||
|
||||
struct sf_procs lendian_sfo_procs = {
|
||||
"-le",
|
||||
".le",
|
||||
{
|
||||
lendian_sfo_aligntyp,
|
||||
lendian_sfo_any,
|
||||
@@ -92,7 +92,7 @@ struct sf_procs lendian_sfo_procs = {
|
||||
|
||||
struct sf_procs lendian_sfi_procs =
|
||||
{
|
||||
"-le",
|
||||
".le",
|
||||
{
|
||||
lendian_sfi_aligntyp,
|
||||
lendian_sfi_any,
|
||||
|
||||
235
src/sfstruct.c
235
src/sfstruct.c
@@ -5,6 +5,11 @@
|
||||
|
||||
#include "hack.h"
|
||||
|
||||
/*
|
||||
* historical structlevel savefile writing and reading routines follow.
|
||||
* These were moved here from save.c and restore.c between 3.6.3 and 3.7.0.
|
||||
*/
|
||||
|
||||
#ifdef TRACE_BUFFERING
|
||||
#ifdef bufon
|
||||
#undef bufon
|
||||
@@ -36,47 +41,165 @@ void FDECL(mread, (int, genericptr_t, unsigned int));
|
||||
void NDECL(minit);
|
||||
void FDECL(bclose, (int));
|
||||
#endif /* TRACE_BUFFERING */
|
||||
STATIC_DCL int FDECL(getidx, (int, int));
|
||||
|
||||
#if defined(UNIX) || defined(WIN32)
|
||||
#define USE_BUFFERING
|
||||
#endif
|
||||
|
||||
/*
|
||||
* historical structlevel savefile writing and reading routines follow.
|
||||
* These were moved here from save.c and restore.c between 3.6.3 and 3.7.0.
|
||||
*/
|
||||
|
||||
struct restore_info restoreinfo = {
|
||||
"externalcomp", 0,
|
||||
};
|
||||
|
||||
#define MAXFD 5
|
||||
enum {NOFLG = 0, NOSLOT = 1};
|
||||
static int bw_sticky[MAXFD] = {-1,-1,-1,-1,-1};
|
||||
static int bw_buffered[MAXFD] = {0,0,0,0,0};
|
||||
#ifdef USE_BUFFERING
|
||||
static FILE *bw_FILE[MAXFD] = {0,0,0,0,0};
|
||||
#endif
|
||||
|
||||
static int bw_fd = -1;
|
||||
static FILE *bw_FILE = 0;
|
||||
static boolean buffering = FALSE;
|
||||
/*
|
||||
* Presumably, the fdopen() to allow use of stdio fwrite()
|
||||
* over write() was done for performance or functionality
|
||||
* reasons to help some particular platform long ago.
|
||||
*
|
||||
* There have been some issues being encountered with the
|
||||
* implementation due to having an individual set of
|
||||
* tracking variables, even though there were nested
|
||||
* sets of open fd (like INSURANCE).
|
||||
*
|
||||
* This uses an individual tracking entry for each fd
|
||||
* being used.
|
||||
*
|
||||
* Some notes:
|
||||
*
|
||||
* Once buffered IO (stdio) has been enabled on the file
|
||||
* associated with a descriptor via fdopen():
|
||||
*
|
||||
* 1. If you use bufoff and bufon to try and toggle the
|
||||
* use of write vs fwrite; the code just tracks which
|
||||
* routine is to be called through the tracking
|
||||
* variables and acts accordingly.
|
||||
* bw_sticky[] - used to find the index number for
|
||||
* the fd that is stored in it, or -1
|
||||
* if it is a free slot.
|
||||
* bw_buffered[] - indicator that buffered IO routines
|
||||
* are available for use.
|
||||
* bw_FILE[] - the non-zero FILE * for use in calling
|
||||
* fwrite() when bw_buffered[] is also
|
||||
* non-zero.
|
||||
*
|
||||
* 2. It is illegal to call close(fd) after fdopen(), you
|
||||
* must always use fclose() on the FILE * from
|
||||
* that point on, so care must be taken to never call
|
||||
* close(fd) on the underlying fd or bad things will
|
||||
* happen.
|
||||
*/
|
||||
|
||||
STATIC_OVL int
|
||||
getidx(fd, flg)
|
||||
int fd, flg;
|
||||
{
|
||||
int i, retval = -1;
|
||||
|
||||
for (i = 0; i < MAXFD; ++i)
|
||||
if (bw_sticky[i] == fd)
|
||||
return i;
|
||||
if (flg == NOSLOT)
|
||||
return retval;
|
||||
for (i = 0; i < MAXFD; ++i)
|
||||
if (bw_sticky[i] < 0) {
|
||||
bw_sticky[i] = fd;
|
||||
retval = i;
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Let caller know that bclose() should handle it (TRUE) */
|
||||
boolean
|
||||
close_check(fd)
|
||||
int fd;
|
||||
{
|
||||
int idx = getidx(fd, NOSLOT);
|
||||
boolean retval = FALSE;
|
||||
|
||||
if (idx >= 0)
|
||||
retval = TRUE;
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
bufon(fd)
|
||||
int fd;
|
||||
int fd;
|
||||
{
|
||||
int idx = getidx(fd, NOFLG);
|
||||
|
||||
if (idx >= 0) {
|
||||
bw_sticky[idx] = fd;
|
||||
#ifdef USE_BUFFERING
|
||||
if(bw_fd != fd) {
|
||||
if(bw_fd >= 0)
|
||||
panic("double buffering unexpected");
|
||||
bw_fd = fd;
|
||||
if((bw_FILE = fdopen(fd, "w")) == 0)
|
||||
panic("buffering of file %d failed", fd);
|
||||
}
|
||||
if (bw_buffered[idx])
|
||||
panic("buffering already enabled");
|
||||
if (!bw_FILE[idx]) {
|
||||
if ((bw_FILE[idx] = fdopen(fd, "w")) == 0)
|
||||
panic("buffering of file %d failed", fd);
|
||||
}
|
||||
bw_buffered[idx] = (bw_FILE[idx] > 0);
|
||||
#else
|
||||
bw_buffered[idx] = 1;
|
||||
#endif
|
||||
buffering = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bufoff(fd)
|
||||
int fd;
|
||||
{
|
||||
bflush(fd);
|
||||
buffering = FALSE;
|
||||
int idx = getidx(fd, NOFLG);
|
||||
|
||||
if (idx >= 0) {
|
||||
bflush(fd);
|
||||
bw_buffered[idx] = 0; /* just a flag that says "use write(fd)" */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bclose(fd)
|
||||
int fd;
|
||||
{
|
||||
int idx = getidx(fd, NOSLOT);
|
||||
|
||||
bufoff(fd); /* sets bw_buffered[idx] = 0 */
|
||||
if (idx >= 0) {
|
||||
#ifdef USE_BUFFERING
|
||||
if (bw_FILE[idx]) {
|
||||
(void) fclose(bw_FILE[idx]);
|
||||
bw_FILE[idx] = 0;
|
||||
} else
|
||||
#endif
|
||||
close(fd);
|
||||
/* return the idx to the pool */
|
||||
bw_sticky[idx] = -1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
bflush(fd)
|
||||
int fd;
|
||||
{
|
||||
int idx = getidx(fd, NOFLG);
|
||||
|
||||
if (idx >= 0) {
|
||||
#ifdef USE_BUFFERING
|
||||
if (bw_FILE[idx]) {
|
||||
if (fflush(bw_FILE[idx]) == EOF)
|
||||
panic("flush of savefile failed!");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -86,69 +209,41 @@ register genericptr_t loc;
|
||||
register unsigned num;
|
||||
{
|
||||
boolean failed;
|
||||
int idx = getidx(fd, NOFLG);
|
||||
|
||||
if (idx >= 0) {
|
||||
#ifdef MFLOPPY
|
||||
bytes_counted += num;
|
||||
if (count_only)
|
||||
return;
|
||||
bytes_counted += num;
|
||||
if (count_only)
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifdef USE_BUFFERING
|
||||
if (buffering) {
|
||||
if (fd != bw_fd)
|
||||
panic("unbuffered write to fd %d (!= %d)", fd, bw_fd);
|
||||
|
||||
failed = (fwrite(loc, (int) num, 1, bw_FILE) != 1);
|
||||
} else
|
||||
#endif /* USE_BUFFERING */
|
||||
{
|
||||
/* lint wants 3rd arg of write to be an int; lint -p an unsigned */
|
||||
if (bw_buffered[idx] && bw_FILE[idx]) {
|
||||
failed = (fwrite(loc, (int) num, 1, bw_FILE[idx]) != 1);
|
||||
} else
|
||||
#endif /* UNIX */
|
||||
{
|
||||
/* lint wants 3rd arg of write to be an int; lint -p an unsigned */
|
||||
#if defined(BSD) || defined(ULTRIX) || defined(WIN32) || defined(_MSC_VER)
|
||||
failed = ((long) write(fd, loc, (int) num) != (long) num);
|
||||
failed = ((long) write(fd, loc, (int) num) != (long) num);
|
||||
#else /* e.g. SYSV, __TURBOC__ */
|
||||
failed = ((long) write(fd, loc, num) != (long) num);
|
||||
failed = ((long) write(fd, loc, num) != (long) num);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
}
|
||||
if (failed) {
|
||||
#if defined(UNIX) || defined(VMS) || defined(__EMX__)
|
||||
if (g.program_state.done_hup)
|
||||
nh_terminate(EXIT_FAILURE);
|
||||
else
|
||||
if (g.program_state.done_hup)
|
||||
nh_terminate(EXIT_FAILURE);
|
||||
else
|
||||
#endif
|
||||
panic("cannot write %u bytes to file #%d", num, fd);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bflush(fd)
|
||||
int fd;
|
||||
{
|
||||
#ifdef USE_BUFFERING
|
||||
if (fd == bw_fd) {
|
||||
if (fflush(bw_FILE) == EOF)
|
||||
panic("flush of savefile failed!");
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
bclose(fd)
|
||||
int fd;
|
||||
{
|
||||
bufoff(fd);
|
||||
#ifdef USE_BUFFERING
|
||||
if (fd == bw_fd) {
|
||||
(void) fclose(bw_FILE);
|
||||
bw_fd = -1;
|
||||
bw_FILE = 0;
|
||||
panic("cannot write %u bytes to file #%d", num, fd);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
(void) nhclose(fd);
|
||||
return;
|
||||
impossible("fd not in list (%d)?", fd);
|
||||
}
|
||||
|
||||
/* ===================================================== */
|
||||
|
||||
void
|
||||
minit()
|
||||
{
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "lev.h"
|
||||
#include "sfproto.h"
|
||||
|
||||
|
||||
/*
|
||||
* All the references to the contents of patchlevel.h have been moved
|
||||
* into makedefs....
|
||||
@@ -342,6 +341,33 @@ unsigned long utdflags;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
store_formatindicator(nhfp)
|
||||
NHFILE *nhfp;
|
||||
{
|
||||
char indicate = 'u';
|
||||
int cmc = 0;
|
||||
|
||||
if (nhfp->mode & WRITING) {
|
||||
if (nhfp->fieldlevel) {
|
||||
indicate = (nhfp->fnidx == ascii) ? 'a' : 'l';
|
||||
sfo_char(nhfp, &indicate, "indicate", "format", 1);
|
||||
cmc = critical_members_count();
|
||||
{
|
||||
#if 0
|
||||
pline("critical-members=%d.", cmc);
|
||||
#endif
|
||||
}
|
||||
sfo_int(nhfp, &cmc, "validate", "critical_members_count", 1);
|
||||
}
|
||||
if (nhfp->structlevel) {
|
||||
indicate = 'h'; /* historical */
|
||||
bwrite(nhfp->fd, (genericptr_t) &indicate, sizeof indicate);
|
||||
bwrite(nhfp->fd, (genericptr_t) &cmc, sizeof cmc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
store_version(nhfp)
|
||||
NHFILE *nhfp;
|
||||
@@ -354,11 +380,13 @@ NHFILE *nhfp;
|
||||
if (nhfp->structlevel) {
|
||||
bufoff(nhfp->fd);
|
||||
/* bwrite() before bufon() uses plain write() */
|
||||
store_formatindicator(nhfp);
|
||||
bwrite(nhfp->fd,(genericptr_t) &version_data,
|
||||
(unsigned) (sizeof version_data));
|
||||
bufon(nhfp->fd);
|
||||
}
|
||||
if (nhfp->fieldlevel) {
|
||||
store_formatindicator(nhfp);
|
||||
sfo_version_info(nhfp, (struct version_info *) &version_data,
|
||||
"version", "version_info", 1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user