From ba0f6ed47f6c93b49c3f750e1e9e18953f13d8d5 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 23 Jun 2019 00:57:38 -0400 Subject: [PATCH] updated files --- include/decl.h | 75 ++++--- include/extern.h | 52 +++-- include/global.h | 2 + include/hack.h | 4 +- include/monst.h | 2 +- include/ntconf.h | 2 - include/pcconf.h | 1 - include/sfproto.h | 2 +- src/cmd.c | 5 +- src/decl.c | 3 - src/do.c | 6 +- src/end.c | 2 +- src/files.c | 272 +++++++++----------------- src/minion.c | 51 ++--- src/muse.c | 7 +- src/objnam.c | 28 +-- src/options.c | 75 ++----- src/pray.c | 13 +- src/restore.c | 276 +------------------------- src/save.c | 429 ++++------------------------------------- src/sfdata.c | 4 +- src/sflendian.c | 4 +- src/sfstruct.c | 235 +++++++++++++++------- src/version.c | 30 ++- sys/unix/Makefile.src | 27 +-- sys/winnt/Makefile.msc | 7 +- sys/winnt/windmain.c | 18 +- sys/winnt/winnt.c | 4 +- 28 files changed, 501 insertions(+), 1135 deletions(-) diff --git a/include/decl.h b/include/decl.h index 87bb872c7..1ff73009c 100644 --- a/include/decl.h +++ b/include/decl.h @@ -7,8 +7,7 @@ #define DECL_H #define E extern - -#if !defined(MFLOPPY) && !defined(VMS) +#if !defined(MFLOPPY) && !defined(VMS) && !defined(WIN32) #define LOCKNAMESIZE (PL_NSIZ + 14) /* long enough for uid+name+.99 */ #define LOCKNAMEINIT "1lock" #define BONESINIT "bonesnn.xxx" @@ -26,32 +25,51 @@ #define BONESINIT "bonesnn.xxx;1" #define BONESSIZE sizeof(BONESINIT) #endif -#endif - -/* This is written to a savefile by a defined size on some platforms, - so let's not create an automatic and unnecessary incompatibility */ -#if defined(UNIX) || defined(__BEOS__) -#define SAVESIZE (PL_NSIZ + 50) /* save/99999player.e */ -#else -#ifdef VMS -#define SAVESIZE (PL_NSIZ + 50) /* [.save]player.e;1 */ -#else #if defined(WIN32) -#define SAVESIZE (PL_NSIZ + 50) /* username-player.NetHack-saved-game */ -#else -#define SAVESIZE FILENAME /* from macconf.h or pcconf.h */ -#endif +#define LOCKNAMESIZE (PL_NSIZ + 25) /* long enough for username+-+name+.99 */ +#define LOCKNAMEINIT "" +#define BONESINIT "bonesnn.xxx" +#define BONESSIZE sizeof(BONESINIT) #endif #endif -/* used in files.c */ -#ifdef HOLD_LOCKFILE_OPEN -struct level_ftrack { - int init; - int fd; /* file descriptor for level file */ - int oflag; /* open flags */ - boolean nethack_thinks_it_is_open; /* Does NetHack think it's open? */ -}; +#define INDEXT ".xxxxxx" /* largest indicator suffix */ +#define INDSIZE sizeof(INDEXT) + +#if defined(UNIX) || defined(__BEOS__) +#define SAVEX "save/99999.e" +#ifndef SAVE_EXTENSION +#define SAVE_EXTENSION "" +#endif +#else /* UNIX || __BEOS__ */ +#ifdef VMS +#define SAVEX "[.save]nnnnn.e;1" +#ifndef SAVE_EXTENSION +#define SAVE_EXTENSION "" +#endif +#else /* VMS */ +#if defined(WIN32) || defined(MICRO) +#define SAVEX "" +#if !defined(SAVE_EXTENSION) +#ifdef MICRO +#define SAVE_EXTENSION ".sav" +#endif +#ifdef WIN32 +#define SAVE_EXTENSION ".NetHack-saved-game" +#endif +#endif /* !SAVE_EXTENSION */ +#endif /* WIN32 || MICRO */ +#endif /* else !VMS */ +#endif /* else !(UNIX || __BEOS__) */ + +#ifndef SAVE_EXTENSION +#define SAVE_EXTENSION "" +#endif + +#ifndef MICRO +#define SAVESIZE (PL_NSIZ + sizeof(SAVEX) + sizeof(SAVE_EXTENSION) + INDSIZE) +#else +#define SAVESIZE FILENAME #endif /* max size of a windowtype option */ @@ -391,13 +409,11 @@ E const char *const monexplain[], invisexplain[], *const oclass_names[]; E const char *fqn_prefix_names[PREFIX_COUNT]; #endif -struct restore_procs { +struct restore_info { const char *name; int mread_flags; - void NDECL((*restore_minit)); - void FDECL((*restore_mread), (int,genericptr_t,unsigned int)); - void FDECL((*restore_bclose), (int)); }; +E struct restore_info restoreinfo; E NEARDATA struct savefile_info sfcap, sfrestinfo, sfsaveinfo; @@ -915,9 +931,6 @@ struct instance_globals { boolean chosen_symset_start; boolean chosen_symset_end; int symset_which_set; -#ifdef HOLD_LOCKFILE_OPEN - struct level_ftrack lftrack; -#endif /*HOLD_LOCKFILE_OPEN*/ char SAVEF[SAVESIZE]; /* holds relative path of save file from playground */ #ifdef MICRO char SAVEP[SAVESIZE]; /* holds path of directory for save file */ diff --git a/include/extern.h b/include/extern.h index afa157aca..829a65b52 100644 --- a/include/extern.h +++ b/include/extern.h @@ -838,9 +838,6 @@ E boolean NDECL(recover_savefile); E void NDECL(assure_syscf_file); #endif E int FDECL(nhclose, (int)); -#ifdef HOLD_LOCKFILE_OPEN -E void NDECL(really_close); -#endif #ifdef DEBUG E boolean FDECL(debugcore, (const char *, BOOLEAN_P)); #endif @@ -2121,8 +2118,6 @@ E int FDECL(restore_menu, (winid)); #endif E void NDECL(minit); E boolean FDECL(lookup_id_mapping, (unsigned, unsigned *)); -E void FDECL(mread, (int, genericptr_t, unsigned int)); -E void FDECL(newread, (NHFILE *, int, int, genericptr_t, unsigned int)); E int FDECL(validate, (NHFILE *, const char *)); E void NDECL(reset_restpref); E void FDECL(set_restpref, (const char *)); @@ -2208,17 +2203,7 @@ E void NDECL(co_false); E void FDECL(savelev, (NHFILE *, XCHAR_P)); #endif E genericptr_t FDECL(mon_to_buffer, (struct monst *, int *)); -E void FDECL(bufon, (int)); -E void FDECL(bufoff, (int)); -E void FDECL(bflush, (int)); -E void FDECL(bwrite, (int, genericptr_t, unsigned int)); -E void FDECL(bclose, (int)); -E void FDECL(def_bclose, (int)); -E void FDECL(newwrite, (NHFILE *, int, int, genericptr_t, unsigned int)); -E void FDECL(newclose, (NHFILE *)); -#if defined(ZEROCOMP) -E void FDECL(zerocomp_bclose, (int)); -#endif +E boolean FDECL(close_check, (int)); E void FDECL(savecemetery, (NHFILE *, struct cemetery **)); E void FDECL(savefruitchn, (NHFILE *)); E void FDECL(store_plname_in_file, (NHFILE *)); @@ -2231,6 +2216,40 @@ E void FDECL(assignlog, (char *, char*, int)); E FILE *FDECL(getlog, (NHFILE *)); E void FDECL(closelog, (NHFILE *)); + +/* ### sfstruct.c ### */ + +#ifndef TRACE_BUFFERING +E void FDECL(newread, (NHFILE *, int, int, genericptr_t, unsigned int)); +E void FDECL(bufon, (int)); +E void FDECL(bufoff, (int)); +E void FDECL(bflush, (int)); +E void FDECL(bwrite, (int, genericptr_t, unsigned int)); +E void FDECL(mread, (int, genericptr_t, unsigned int)); +E void NDECL(minit); +E void FDECL(bclose, (int)); +#else +#define bufon(x) Bufon(x,__FUNCTION__, __LINE__) +#define bufoff(x) Bufoff(x,__FUNCTION__, __LINE__) +#define bflush(x) Bflush(x,__FUNCTION__, __LINE__) +#define bwrite(x,y,z) Bwrite(x,y,z,__FUNCTION__, __LINE__) +#define bclose(x) Bclose(x,__FUNCTION__, __LINE__) +#define mread(x,y,z) Mread(x,y,z,__FUNCTION__, __LINE__) +#define minit() Minit(__FUNCTION__, __LINE__) +#endif +E void FDECL(Bufon, (int, const char *, int)); +E void FDECL(Bufoff, (int, const char *, int)); +E void FDECL(Bflush, (int, const char *, int)); +E void FDECL(Bwrite, (int, genericptr_t, unsigned int, const char *, int)); +E void FDECL(Bread, (int, genericptr_t, unsigned int, const char *, int)); +E void FDECL(Binit,(const char *, int)); +E void FDECL(Bclose, (int, const char *, int)); +E void FDECL(Mread, (int, genericptr_t, unsigned int, const char *, int)); +E void FDECL(Minit, (const char *, int)); +#if defined(ZEROCOMP) +E void FDECL(zerocomp_bclose, (int)); +#endif + /* ### shk.c ### */ E void FDECL(setpaid, (struct monst *)); @@ -2643,6 +2662,7 @@ E boolean FDECL(comp_times, (long)); E boolean FDECL(check_version, (struct version_info *, const char *, BOOLEAN_P, unsigned long)); E boolean FDECL(uptodate, (NHFILE *, const char *, unsigned long)); +E void FDECL(store_formatindicator, (NHFILE *)); E void FDECL(store_version, (NHFILE *)); E unsigned long FDECL(get_feature_notice_ver, (char *)); E unsigned long NDECL(get_current_feature_ver); diff --git a/include/global.h b/include/global.h index f493d8a3e..e6f0ec4a4 100644 --- a/include/global.h +++ b/include/global.h @@ -95,6 +95,7 @@ typedef uchar nhsym; #endif #endif +#if 0 /* comment out to test effects of each #define -- these will probably * disappear eventually */ @@ -102,6 +103,7 @@ typedef uchar nhsym; #define RLECOMP /* run-length compression of levl array - JLee */ #define ZEROCOMP /* zero-run compression of everything - Olaf Seibert */ #endif +#endif /* #define SPECIALIZATION */ /* do "specialized" version of new topology */ diff --git a/include/hack.h b/include/hack.h index 07928ddc6..c7807f015 100644 --- a/include/hack.h +++ b/include/hack.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 hack.h $NHDT-Date: 1561019041 2019/06/20 08:24:01 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.106 $ */ +/* NetHack 3.6 hack.h $NHDT-Date: 1559227823 2019/05/30 14:50:23 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.105 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2017. */ /* NetHack may be freely redistributed. See license for details. */ @@ -572,6 +572,6 @@ enum bodypart_types { #endif #define DEVTEAM_EMAIL "devteam@nethack.org" -#define DEVTEAM_URL "https://www.nethack.org/" +#define DEVTEAM_URL "http://www.nethack.org" #endif /* HACK_H */ diff --git a/include/monst.h b/include/monst.h index 697164f8d..bc8f939c5 100644 --- a/include/monst.h +++ b/include/monst.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 monst.h $NHDT-Date: 1561053561 2019/06/20 17:59:21 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.33 $ */ +/* NetHack 3.6 monst.h $NHDT-Date: 1559994623 2019/06/08 11:50:23 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.32 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/ntconf.h b/include/ntconf.h index 2647c243f..c2b0b3af0 100644 --- a/include/ntconf.h +++ b/include/ntconf.h @@ -18,8 +18,6 @@ #define PC_LOCKING /* Prevent overwrites of aborted or in-progress games */ /* without first receiving confirmation. */ -#define HOLD_LOCKFILE_OPEN /* Keep an exclusive lock on the .0 file */ - #define SELF_RECOVER /* Allow the game itself to recover from an aborted \ game */ diff --git a/include/pcconf.h b/include/pcconf.h index 736c62953..875530efd 100644 --- a/include/pcconf.h +++ b/include/pcconf.h @@ -180,7 +180,6 @@ #undef lock #include /* kbhit() */ #define PC_LOCKING -#define HOLD_LOCKFILE_OPEN #define SELF_RECOVER /* NetHack itself can recover games */ #endif diff --git a/include/sfproto.h b/include/sfproto.h index 1e67337f6..f72baec0b 100644 --- a/include/sfproto.h +++ b/include/sfproto.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 sfproto.h Sat Jun 22 23:55:47 2019 */ +/* NetHack 3.7 sfproto.h Sat Jun 22 22:53:12 2019 */ /* Copyright (c) NetHack Development Team 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/cmd.c b/src/cmd.c index 6cfd4275a..f81b53d81 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -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; } diff --git a/src/decl.c b/src/decl.c index 11c904a00..d24e9937a 100644 --- a/src/decl.c +++ b/src/decl.c @@ -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 */ diff --git a/src/do.c b/src/do.c index b294828f6..95fbcc1a6 100644 --- a/src/do.c +++ b/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); diff --git a/src/end.c b/src/end.c index 43699f368..95f4a0a12 100644 --- a/src/end.c +++ b/src/end.c @@ -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 diff --git a/src/files.c b/src/files.c index ba3128924..7e3748b44 100644 --- a/src/files.c +++ b/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 #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. diff --git a/src/minion.c b/src/minion.c index 7619352f4..de6018a8d 100644 --- a/src/minion.c +++ b/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; diff --git a/src/muse.c b/src/muse.c index 83372e500..d1ee5472a 100644 --- a/src/muse.c +++ b/src/muse.c @@ -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); } diff --git a/src/objnam.c b/src/objnam.c index d864368b1..fc26bdff5 100644 --- a/src/objnam.c +++ b/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 " [ 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 " */ 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; } diff --git a/src/options.c b/src/options.c index ed4396c67..e6cfe5224 100644 --- a/src/options.c +++ b/src/options.c @@ -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); } } diff --git a/src/pray.c b/src/pray.c index 8604c94ba..5bc7e6eba 100644 --- a/src/pray.c +++ b/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. diff --git a/src/restore.c b/src/restore.c index 312bc083f..d10a6ec88 100644 --- a/src/restore.c +++ b/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*/ diff --git a/src/save.c b/src/save.c index 063646cc6..192218886 100644 --- a/src/save.c +++ b/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*/ diff --git a/src/sfdata.c b/src/sfdata.c index 32b6a7441..a311d4613 100644 --- a/src/sfdata.c +++ b/src/sfdata.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 diff --git a/src/sflendian.c b/src/sflendian.c index c346b3fd5..617176de3 100644 --- a/src/sflendian.c +++ b/src/sflendian.c @@ -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, diff --git a/src/sfstruct.c b/src/sfstruct.c index 1da4b465e..b360f3c54 100644 --- a/src/sfstruct.c +++ b/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() { diff --git a/src/version.c b/src/version.c index b42882fa8..e599dc277 100644 --- a/src/version.c +++ b/src/version.c @@ -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); } diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index bffc6cbe7..0162bdaf0 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -448,7 +448,7 @@ HACKCSRC = allmain.c alloc.c apply.c artifact.c attrib.c ball.c bones.c \ mplayer.c mthrowu.c muse.c music.c o_init.c objects.c objnam.c \ options.c pager.c pickup.c pline.c polyself.c potion.c pray.c \ priest.c quest.c questpgr.c read.c rect.c region.c restore.c \ - rip.c rnd.c role.c rumors.c save.c \ + rip.c rnd.c role.c rumors.c save.c sfstruct.c \ sfbase.c sfdata.c sfascii.c sflendian.c \ shk.c shknam.c sit.c sounds.c \ sp_lev.c spell.c steal.c steed.c sys.c teleport.c timeout.c \ @@ -517,7 +517,7 @@ HOBJ = $(FIRSTOBJ) allmain.o alloc.o apply.o artifact.o attrib.o ball.o \ mplayer.o mthrowu.o muse.o music.o o_init.o objnam.o options.o \ pager.o pickup.o pline.o polyself.o potion.o pray.o priest.o \ quest.o questpgr.o read.o rect.o region.o restore.o rip.o rnd.o \ - role.o rumors.o save.o \ + role.o rumors.o save.o sfstruct.o \ sfbase.o sfdata.o sfascii.o sflendian.o \ shk.o shknam.o sit.o sounds.o sp_lev.o spell.o sys.o \ steal.o steed.o teleport.o timeout.o topten.o track.o trap.o u_init.o \ @@ -664,22 +664,23 @@ tile.c: ../win/share/tilemap.c $(HACK_H) # readtags dependencies # # -../util/readtags: - @( cd ../util ; $(MAKE) readtags ) - -../util/nethack.tags: - @( cd ../util ; $(MAKE) nethack.tags ) - +sfstruct.o: sfstruct.c $(HACK_H) sfbase.o: sfbase.c $(HACK_H) ../include/sfproto.h ../include/sfprocs.h sfascii.o: sfascii.c $(HACK_H) ../include/sfprocs.h sflendian.o: sflendian.c $(HACK_H) ../include/sfprocs.h sfdata.o: sfdata.c $(HACK_H) ../include/sfprocs.h -sfdata.c: ../util/readtags ../util/nethack.tags - @( cd ../util ; ./readtags ) - -../include/sfproto.h: ../util/readtags ../util/nethack.tags - @( cd ../util ; ./readtags ) +#../util/readtags: +# @( cd ../util ; $(MAKE) readtags ) +# +#../util/nethack.tags: +# @( cd ../util ; $(MAKE) nethack.tags ) +# +#sfdata.c: ../util/readtags ../util/nethack.tags +# @( cd ../util ; ./readtags ) +# +#../include/sfproto.h: ../util/readtags ../util/nethack.tags +# @( cd ../util ; ./readtags ) # date.h should be remade any time any of the source or include code # is modified. Unfortunately, this would make the contents of this diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 5e9a21b04..5a09de905 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -236,8 +236,8 @@ VOBJ24 = $(O)track.o $(O)trap.o $(O)u_init.o $(O)uhitm.o VOBJ25 = $(O)vault.o $(O)vis_tab.o $(O)vision.o $(O)weapon.o VOBJ26 = $(O)were.o $(O)wield.o $(O)windows.o $(O)wizard.o VOBJ27 = $(O)worm.o $(O)worn.o $(O)write.o $(O)zap.o -VOBJ28 = $(O)sfbase.o $(O)sfdata.o $(O)sfascii.o $(O)sflendian.o -#VOBJ29 = +VOBJ28 = $(O)sfbase.o $(O)sfdata.o +VOBJ29 = $(O)sfstruct.o $(O)sfascii.o $(O)sflendian.o DLBOBJ = $(O)dlb.o @@ -1504,6 +1504,9 @@ $(O)sfbase.o: $(HACK_H) $(INCL)\sfproto.h $(INCL)\sfprocs.h \ $(O)sfdata.o: $(HACK_H) $(INCL)\sfprocs.h $(SRC)\sfdata.c @$(cc) $(cflagsBuild) -Fo$@ $(SRC)\sfdata.c +$(O)sfstruct.o: $(HACK_H) $(SRC)\sfstruct.c + @$(cc) $(cflagsBuild) -Fo$@ $(SRC)\sfstruct.c + $(O)sfascii.o: $(HACK_H) $(INCL)\sfprocs.h $(SRC)\sfascii.c @$(cc) $(cflagsBuild) -Fo$@ $(SRC)\sfascii.c diff --git a/sys/winnt/windmain.c b/sys/winnt/windmain.c index 975638c06..2ff4ab411 100644 --- a/sys/winnt/windmain.c +++ b/sys/winnt/windmain.c @@ -798,7 +798,7 @@ getlock() } /* regularize(lock); */ /* already done in pcmain */ - Sprintf(tbuf, "%s", fqname(g.lock, LEVELPREFIX, 0)); + /*Sprintf(tbuf, "%s", fqname(g.lock, LEVELPREFIX, 0)); */ set_levelfile_name(g.lock, 0); fq_lock = fqname(g.lock, LEVELPREFIX, 1); if ((fd = open(fq_lock, 0)) == -1) { @@ -807,21 +807,7 @@ getlock() #if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS) chdirx(orgdir, 0); #endif -#if defined(HOLD_LOCKFILE_OPEN) - if (errno == EACCES) { - Strcpy( - oops, - "\nThere are files from a game in progress under your name."); - Strcat(oops, "\nThe files are locked or inaccessible."); - Strcat(oops, " Is the other game still running?\n"); - if (strlen(fq_lock) < ((OOPS_BUFSZ - 16) - strlen(oops))) - Sprintf(eos(oops), "Cannot open %s", fq_lock); - Strcat(oops, "\n"); - unlock_file(HLOCK); - raw_print(oops); - } else -#endif - error("Bad directory or name: %s\n%s\n", fq_lock, + error("Bad directory or name: %s\n%s\n", fq_lock, strerror(errno)); unlock_file(HLOCK); Sprintf(oops, "Cannot open %s", fq_lock); diff --git a/sys/winnt/winnt.c b/sys/winnt/winnt.c index f6a9aa791..f06775a4b 100644 --- a/sys/winnt/winnt.c +++ b/sys/winnt/winnt.c @@ -505,8 +505,10 @@ int code; a little cleaner than the stdio one */ windowprocs.win_nhgetch = windows_console_custom_nhgetch; } - if (getreturn_enabled) + if (getreturn_enabled) { + raw_print("\n"); wait_synch(); + } exit(code); }