From 247626dfe552ece836bd404e491b74a646c3e467 Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 22 Nov 2018 10:15:43 -0800 Subject: [PATCH 01/14] Removed unnecessary use of static for nocreate values. If multiple games are played without exiting the process, on the second new player creation the nocreate values will already be set based on the first player creation. --- src/u_init.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/u_init.c b/src/u_init.c index 5b5c5113f..71da5a84a 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -974,15 +974,16 @@ register struct trobj *trop; struct obj *obj; int otyp, i; - while (trop->trclass) { + NEARDATA short nocreate = STRANGE_OBJECT; + NEARDATA short nocreate2 = STRANGE_OBJECT; + NEARDATA short nocreate3 = STRANGE_OBJECT; + NEARDATA short nocreate4 = STRANGE_OBJECT; + + while (trop->trclass) { otyp = (int) trop->trotyp; if (otyp != UNDEF_TYP) { obj = mksobj(otyp, TRUE, FALSE); } else { /* UNDEF_TYP */ - static NEARDATA short nocreate = STRANGE_OBJECT; - static NEARDATA short nocreate2 = STRANGE_OBJECT; - static NEARDATA short nocreate3 = STRANGE_OBJECT; - static NEARDATA short nocreate4 = STRANGE_OBJECT; /* * For random objects, do not create certain overly powerful * items: wand of wishing, ring of levitation, or the From 250ca464bc2aa5ec565b73c2cbaf9308c8592a70 Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 22 Nov 2018 13:01:58 -0800 Subject: [PATCH 02/14] Modified how we initialize save file info. There should be no net change other then improving code maintenance. --- include/global.h | 27 +++++++++++++++++++++++++++ src/decl.c | 42 ++---------------------------------------- 2 files changed, 29 insertions(+), 40 deletions(-) diff --git a/include/global.h b/include/global.h index 154c49ebe..d57352611 100644 --- a/include/global.h +++ b/include/global.h @@ -294,15 +294,42 @@ struct savefile_info { unsigned long sfi3; /* thirdparty */ }; #ifdef NHSTDC +#define SFI_ZERO (0UL) #define SFI1_EXTERNALCOMP (1UL) #define SFI1_RLECOMP (1UL << 1) #define SFI1_ZEROCOMP (1UL << 2) #else +#define SFI_ZERO (0L) #define SFI1_EXTERNALCOMP (1L) #define SFI1_RLECOMP (1L << 1) #define SFI1_ZEROCOMP (1L << 2) #endif +#if defined(COMPRESS) || defined(ZLIB_COMP) +#define SFI1_DEFAULT_EXTERNALCOMP SFI1_EXTERNALCOMP +#else +#define SFI1_DEFAULT_EXTERNALCOMP SFI_ZERO +#endif + +#if defined(ZEROCOMP) +#define SFI1_DEFAULT_ZEROCOMP SFI1_EXTERNALCOMP +#else +#define SFI1_DEFAULT_ZEROCOMP SFI_ZERO +#endif + +#if defined(RLECOMP) +#define SFI1_DEFAULT_RLECOMP SFI1_RLECOMP +#else +#define SFI1_DEFAULT_RLECOMP SFI_ZERO +#endif + +#define SFI1_DEFAULT (SFI1_DEFAULT_EXTERNALCOMP | \ + SFI1_DEFAULT_ZEROCOMP | \ + SFI1_DEFAULT_RLECOMP) +#define SFI2_DEFAULT SFI_ZERO +#define SFI3_DEFAULT SFI_ZERO + + /* * Configurable internal parameters. * diff --git a/src/decl.c b/src/decl.c index ffd9ef974..15c28d2a1 100644 --- a/src/decl.c +++ b/src/decl.c @@ -285,49 +285,11 @@ char *fqn_prefix_names[PREFIX_COUNT] = { #endif NEARDATA struct savefile_info sfcap = { -#ifdef NHSTDC - 0x00000000UL -#else - 0x00000000L -#endif -#if defined(COMPRESS) || defined(ZLIB_COMP) - | SFI1_EXTERNALCOMP -#endif -#if defined(ZEROCOMP) - | SFI1_ZEROCOMP -#endif -#if defined(RLECOMP) - | SFI1_RLECOMP -#endif - , -#ifdef NHSTDC - 0x00000000UL, 0x00000000UL -#else - 0x00000000L, 0x00000000L -#endif + SFI1_DEFAULT, SFI2_DEFAULT, SFI3_DEFAULT }; NEARDATA struct savefile_info sfrestinfo, sfsaveinfo = { -#ifdef NHSTDC - 0x00000000UL -#else - 0x00000000L -#endif -#if defined(COMPRESS) || defined(ZLIB_COMP) - | SFI1_EXTERNALCOMP -#endif -#if defined(ZEROCOMP) - | SFI1_ZEROCOMP -#endif -#if defined(RLECOMP) - | SFI1_RLECOMP -#endif - , -#ifdef NHSTDC - 0x00000000UL, 0x00000000UL -#else - 0x00000000L, 0x00000000L -#endif + SFI1_DEFAULT, SFI2_DEFAULT, SFI3_DEFAULT }; struct plinemsg_type *plinemsg_types = (struct plinemsg_type *) 0; From c1dbae9f1fcdb3ff850107a0152c88b6a8f0cb07 Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 22 Nov 2018 13:05:44 -0800 Subject: [PATCH 03/14] Added PLAYAGAIN experimental support definition. --- include/config.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/config.h b/include/config.h index 4f242679a..761262c4b 100644 --- a/include/config.h +++ b/include/config.h @@ -552,6 +552,11 @@ typedef unsigned char uchar; #endif +/* PLAYAGAIN is support for allowing the game shell to stay open after the player + saves or dies. This requires that the game engine can be re-entered to start + another game. This support is primarily about ensuring that game engine + state is cleaned up properly to allow the game engine to be re-initialized. */ +/* #define PLAYAGAIN */ /* End of Section 4 */ From d5c792a87cce18f1a985a8387a9b759e62ed50ce Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 22 Nov 2018 14:21:31 -0800 Subject: [PATCH 04/14] Revert "Modified how we initialize save file info." This reverts commit 250ca464bc2aa5ec565b73c2cbaf9308c8592a70. --- include/global.h | 27 --------------------------- src/decl.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/include/global.h b/include/global.h index d57352611..154c49ebe 100644 --- a/include/global.h +++ b/include/global.h @@ -294,42 +294,15 @@ struct savefile_info { unsigned long sfi3; /* thirdparty */ }; #ifdef NHSTDC -#define SFI_ZERO (0UL) #define SFI1_EXTERNALCOMP (1UL) #define SFI1_RLECOMP (1UL << 1) #define SFI1_ZEROCOMP (1UL << 2) #else -#define SFI_ZERO (0L) #define SFI1_EXTERNALCOMP (1L) #define SFI1_RLECOMP (1L << 1) #define SFI1_ZEROCOMP (1L << 2) #endif -#if defined(COMPRESS) || defined(ZLIB_COMP) -#define SFI1_DEFAULT_EXTERNALCOMP SFI1_EXTERNALCOMP -#else -#define SFI1_DEFAULT_EXTERNALCOMP SFI_ZERO -#endif - -#if defined(ZEROCOMP) -#define SFI1_DEFAULT_ZEROCOMP SFI1_EXTERNALCOMP -#else -#define SFI1_DEFAULT_ZEROCOMP SFI_ZERO -#endif - -#if defined(RLECOMP) -#define SFI1_DEFAULT_RLECOMP SFI1_RLECOMP -#else -#define SFI1_DEFAULT_RLECOMP SFI_ZERO -#endif - -#define SFI1_DEFAULT (SFI1_DEFAULT_EXTERNALCOMP | \ - SFI1_DEFAULT_ZEROCOMP | \ - SFI1_DEFAULT_RLECOMP) -#define SFI2_DEFAULT SFI_ZERO -#define SFI3_DEFAULT SFI_ZERO - - /* * Configurable internal parameters. * diff --git a/src/decl.c b/src/decl.c index 15c28d2a1..ffd9ef974 100644 --- a/src/decl.c +++ b/src/decl.c @@ -285,11 +285,49 @@ char *fqn_prefix_names[PREFIX_COUNT] = { #endif NEARDATA struct savefile_info sfcap = { - SFI1_DEFAULT, SFI2_DEFAULT, SFI3_DEFAULT +#ifdef NHSTDC + 0x00000000UL +#else + 0x00000000L +#endif +#if defined(COMPRESS) || defined(ZLIB_COMP) + | SFI1_EXTERNALCOMP +#endif +#if defined(ZEROCOMP) + | SFI1_ZEROCOMP +#endif +#if defined(RLECOMP) + | SFI1_RLECOMP +#endif + , +#ifdef NHSTDC + 0x00000000UL, 0x00000000UL +#else + 0x00000000L, 0x00000000L +#endif }; NEARDATA struct savefile_info sfrestinfo, sfsaveinfo = { - SFI1_DEFAULT, SFI2_DEFAULT, SFI3_DEFAULT +#ifdef NHSTDC + 0x00000000UL +#else + 0x00000000L +#endif +#if defined(COMPRESS) || defined(ZLIB_COMP) + | SFI1_EXTERNALCOMP +#endif +#if defined(ZEROCOMP) + | SFI1_ZEROCOMP +#endif +#if defined(RLECOMP) + | SFI1_RLECOMP +#endif + , +#ifdef NHSTDC + 0x00000000UL, 0x00000000UL +#else + 0x00000000L, 0x00000000L +#endif }; struct plinemsg_type *plinemsg_types = (struct plinemsg_type *) 0; From 95208cff1dcf9df9e56f45ab280bf66a02a9cc6c Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 22 Nov 2018 15:03:00 -0800 Subject: [PATCH 05/14] Added nhassert() support to tile2bmp. --- win/share/tile2bmp.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/win/share/tile2bmp.c b/win/share/tile2bmp.c index ca2c7dd73..6722bbc26 100644 --- a/win/share/tile2bmp.c +++ b/win/share/tile2bmp.c @@ -360,3 +360,10 @@ pixel (*pixels)[TILE_X]; } } } + +/* nhassert_failed is called when an nhassert's condition is false */ +void nhassert_failed(const char * exp, const char * file, int line) +{ + Fprintf(stderr, "NHASSERT(%s) in '%s' at line %d\n", exp, file, line); + exit(EXIT_FAILURE); +} From 3e8d98dee5403fd6610a15b2bcacd08a856d7984 Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 22 Nov 2018 15:03:26 -0800 Subject: [PATCH 06/14] Added nhassert() support. --- util/lev_main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/util/lev_main.c b/util/lev_main.c index ecf7a444c..729549791 100644 --- a/util/lev_main.c +++ b/util/lev_main.c @@ -1637,4 +1637,11 @@ short ospeed; #endif #endif /* STRICT_REF_DEF */ +/* nhassert_failed is called when an nhassert's condition is false */ +void nhassert_failed(const char * exp, const char * file, int line) +{ + fprintf(stderr, "NHASSERT(%s) in '%s' at line %d\n", exp, file, line); + exit(EXIT_FAILURE); +} + /*lev_main.c*/ From 6737fee07d9cdc7ac88bf003c32f97a5b7a07a6a Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 22 Nov 2018 15:20:17 -0800 Subject: [PATCH 07/14] Added decl_early_init() which is called when PLAYAGAIN is supported. decl_early_init() is called when we are starting a game. On first start, it validates that global state is in the expected state. When called on subsequent starts, it initializes global state to expected state. --- include/config.h | 11 +- include/extern.h | 3 + src/decl.c | 259 ++++++++++++++++++++++++++++++++++++++++++++ sys/share/pcmain.c | 4 + sys/winnt/stubs.c | 3 + win/win32/winhack.c | 3 + 6 files changed, 279 insertions(+), 4 deletions(-) diff --git a/include/config.h b/include/config.h index 761262c4b..d4f67e1ac 100644 --- a/include/config.h +++ b/include/config.h @@ -552,10 +552,13 @@ typedef unsigned char uchar; #endif -/* PLAYAGAIN is support for allowing the game shell to stay open after the player - saves or dies. This requires that the game engine can be re-entered to start - another game. This support is primarily about ensuring that game engine - state is cleaned up properly to allow the game engine to be re-initialized. */ +/* PLAYAGAIN support for allowing the game shell to stay open after the player + * saves or dies. This requires that the game engine can be re-entered to + * start another game. + * + * This support does not include supporting playing another game when + * a panic has occured due to undetermined state the engine is left in after a + * panic */ /* #define PLAYAGAIN */ /* End of Section 4 */ diff --git a/include/extern.h b/include/extern.h index 89910b0bb..d3a251b83 100644 --- a/include/extern.h +++ b/include/extern.h @@ -251,6 +251,9 @@ E void FDECL(destroy_drawbridge, (int, int)); /* ### decl.c ### */ E void NDECL(decl_init); +#ifdef PLAYAGAIN +E void NDECL(decl_early_init); +#endif /* ### detect.c ### */ diff --git a/src/decl.c b/src/decl.c index ffd9ef974..6c26b4422 100644 --- a/src/decl.c +++ b/src/decl.c @@ -284,6 +284,31 @@ char *fqn_prefix_names[PREFIX_COUNT] = { }; #endif +#ifdef PLAYAGAIN +const struct savefile_info default_sfinfo = { +#ifdef NHSTDC + 0x00000000UL +#else + 0x00000000L +#endif +#if defined(COMPRESS) || defined(ZLIB_COMP) + | SFI1_EXTERNALCOMP +#endif +#if defined(ZEROCOMP) + | SFI1_ZEROCOMP +#endif +#if defined(RLECOMP) + | SFI1_RLECOMP +#endif + , +#ifdef NHSTDC + 0x00000000UL, 0x00000000UL +#else + 0x00000000L, 0x00000000L +#endif +}; +#endif + NEARDATA struct savefile_info sfcap = { #ifdef NHSTDC 0x00000000UL @@ -346,4 +371,238 @@ decl_init() return; } +#ifdef PLAYAGAIN + +static boolean s_firstStart = TRUE; + +static boolean +decl_is_block_zero(p, n) +unsigned char * p; +int n; +{ + static unsigned char zeroblock[512] = { 0 }; + unsigned char * sentinel = p + n; + while (p < sentinel) { + int c = (n < sizeof(zeroblock) ? n : sizeof(zeroblock)); + if (memcmp(p, zeroblock, c) != 0) return FALSE; + p += c; + } + return TRUE; +} + +static void +decl_zero_block(p, n) +unsigned char * p; +int n; +{ + nhassert(!s_firstStart || decl_is_block_zero(p, n)); + memset(p, 0, n); +} + +#define ZEROARRAY(x) decl_zero_block((void *) &x[0], 0, sizeof(x)) +#define ZEROARRAYN(x,n) decl_zero_block((void *) &x[0], 0, sizeof(x[0])*(n)) +#define ZERO(x) decl_zero_block((void *) &x, 0, sizeof(x)) +#define ZEROPTR(x) { nhassert(x == NULL); x = NULL; } +#define ZEROPTRNOCHECK(x) { x = NULL; } + +/* decl_early_init() is called when we are starting a game. On first + * start, it validates that global state is in the expected state. + * When called on subsequent starts, it initializes global state to + * expected state. + * + * In the case that of global pointers, on subsequent starts it will + * panic if it finds a non-NULL pointer with the assumption that a + * pointer has leaked. */ + +void +decl_early_init() +{ + hackpid = 0; +#if defined(UNIX) || defined(VMS) + locknum = 0; +#endif +#ifdef DEF_PAGER + catmore = 0; +#endif + + ZEROARRAY(bases); + + multi = 0; + multi_reason = NULL; + nroom = 0; + nsubroom = 0; + occtime = 0; + + x_maze_max = (COLNO - 1) & ~1; + y_maze_max = (ROWNO - 1) & ~1; + + otg_temp = 0; + + ZERO(dungeon_topology); + ZERO(quest_status); + + warn_obj_cnt = 0; + ZEROARRAYN(smeq, MAXNROFROOMS + 1); + doorindex = 0; + save_cm = NULL; + + ZERO(killer); + done_money = 0; + nomovemsg = NULL; + ZEROARRAY(plname); + ZEROARRAY(pl_character); + pl_race = '\0'; + + ZEROARRAY(pl_fruit); + ffruit = NULL; + + ZEROARRAY(tune); + + occtxt = NULL; + + yn_number = 0; + +#if defined(MICRO) || defined(WIN32) + ZEROARRAYN(hackdir, PATHLEN); +#ifdef MICRO + ZEROARRAYN(levels, PATHLEN); +#endif /* MICRO */ +#endif /* MICRO || WIN32 */ + +#ifdef MFLOPPY + ZEROARRAYN(permbones, PATHLEN); + ramdisk = FALSE; + saveprompt = TRUE; +#endif + + ZEROARRAY(level_info); + + ZERO(program_state); + + tbx = 0; + tby = 0; + + ZERO(m_shot); + + ZEROARRAYN(dungeons, MAXDUNGEON); + ZEROPTR(sp_levchn); + ZERO(upstair); + ZERO(dnstair); + ZERO(upladder); + ZERO(dnladder); + ZERO(sstairs); + ZERO(updest); + ZERO(dndest); + ZERO(inv_pos); + + defer_see_monsters = FALSE; + in_mklev = FALSE; + stoned = FALSE; + unweapon = FALSE; + mrg_to_wielded = FALSE; + + in_steed_dismounting = FALSE; + + ZERO(bhitpos); + ZEROARRAY(doors); + + ZEROARRAY(rooms); + subrooms = &rooms[MAXNROFROOMS + 1]; + upstairs_room = NULL; + dnstairs_room = NULL; + sstairs_room = NULL; + + ZERO(level); + ZEROPTR(ftrap); + ZERO(youmonst); + ZERO(context); + ZERO(flags); +#ifdef SYSFLAGS + ZERO(sysflags); +#endif + ZERO(iflags); + ZERO(u); + ZERO(ubirthday); + ZERO(urealtime); + + ZEROARRAY(lastseentyp); + + ZEROPTR(invent); + ZEROPTRNOCHECK(uwep); + ZEROPTRNOCHECK(uarm); + ZEROPTRNOCHECK(uswapwep); + ZEROPTRNOCHECK(uquiver); + ZEROPTRNOCHECK(uarmu); + ZEROPTRNOCHECK(uskin); + ZEROPTRNOCHECK(uarmc); + ZEROPTRNOCHECK(uarmh); + ZEROPTRNOCHECK(uarms); + ZEROPTRNOCHECK(uarmg); + ZEROPTRNOCHECK(uarmf); + ZEROPTRNOCHECK(uamul); + ZEROPTRNOCHECK(uright); + ZEROPTRNOCHECK(uleft); + ZEROPTRNOCHECK(ublindf); + ZEROPTRNOCHECK(uchain); + ZEROPTRNOCHECK(uball); + + ZEROPTR(current_wand); + ZEROPTR(thrownobj); + ZEROPTR(kickedobj); + + ZEROARRAYN(spl_book, MAXSPELL + 1); + + moves = 1; + monstermoves = 1; + + wailmsg = 0L; + + ZEROPTR(migrating_objs); + ZEROPTR(billobjs); + + ZERO(zeroobj); + ZERO(zeromonst); + ZERO(zeroany); + + ZEROARRAYN(dogname, PL_PSIZ); + ZEROARRAYN(catname, PL_PSIZ); + ZEROARRAYN(horsename, PL_PSIZ); + preferred_pet = 0; + ZEROPTR(mydogs); + ZEROPTR(migrating_mons); + + ZEROARRAY(mvitals); + + ZEROPTR(menu_colorings); + + vision_full_recalc = 0; + viz_array = NULL; + + WIN_MESSAGE = WIN_ERR; +#ifndef STATUS_VIA_WINDOWPORT + WIN_STATUS = WIN_ERR; +#endif + WIN_MAP = WIN_ERR; + WIN_INVEN = WIN_ERR; + + ZEROARRAYN(toplines, TBUFSZ); + ZERO(tc_gbl_data); + ZEROARRAYN(fqn_prefix, PREFIX_COUNT); + + sfcap = default_sfinfo; + sfrestinfo = default_sfinfo; + sfsaveinfo = default_sfinfo; + + ZEROPTR(plinemsg_types); + +#ifdef PANICTRACE + ARGV0 = NULL; +#endif + + nhUse_dummy = 0; + + s_firstStart = FALSE; +} +#endif + /*decl.c*/ diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index 93674ab34..9ffbeca51 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -97,7 +97,11 @@ char *argv[]; nethack_enter(argc, argv); +#ifdef PLAYAGAIN + decl_early_init(); +#endif sys_early_init(); + #if defined(WIN32) && defined(TTY_GRAPHICS) Strcpy(default_window_sys, "tty"); #else diff --git a/sys/winnt/stubs.c b/sys/winnt/stubs.c index bb5ad82e4..ff3cf5919 100644 --- a/sys/winnt/stubs.c +++ b/sys/winnt/stubs.c @@ -37,6 +37,9 @@ char *argv[]; { boolean resuming; +#ifdef PLAYAGAIN + decl_early_init(); +#endif sys_early_init(); Strcpy(default_window_sys, "tty"); resuming = pcmain(argc, argv); diff --git a/win/win32/winhack.c b/win/win32/winhack.c index 9dcbb4e4b..6db66261e 100644 --- a/win/win32/winhack.c +++ b/win/win32/winhack.c @@ -97,6 +97,9 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, win10_init(); +#ifdef PLAYAGAIN + decl_early_init(); +#endif sys_early_init(); /* init applicatio structure */ From 79e0a11c15ba03af2dc57359e7b0b42b4767576a Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 22 Nov 2018 15:40:31 -0800 Subject: [PATCH 08/14] Previous encumberance state moved to decl.c. --- include/decl.h | 3 +++ src/decl.c | 5 +++++ src/pickup.c | 1 - 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/decl.h b/include/decl.h index 992e86ad5..7fcde0c6c 100644 --- a/include/decl.h +++ b/include/decl.h @@ -437,6 +437,9 @@ struct early_opt { boolean valallowed; }; +/* encumbrance */ +E int oldcap; + #undef E #endif /* DECL_H */ diff --git a/src/decl.c b/src/decl.c index 6c26b4422..c3397a048 100644 --- a/src/decl.c +++ b/src/decl.c @@ -214,6 +214,9 @@ NEARDATA struct monst *migrating_mons = (struct monst *) 0; NEARDATA struct mvitals mvitals[NUMMONS]; +/* originally from pickup.c */ +int oldcap = 0; /* encumbrance */ + NEARDATA struct c_color_names c_color_names = { "black", "amber", "golden", "light blue", "red", "green", "silver", "blue", "purple", "white", "orange" @@ -525,6 +528,8 @@ decl_early_init() ZERO(ubirthday); ZERO(urealtime); + ZERO(oldcap); + ZEROARRAY(lastseentyp); ZEROPTR(invent); diff --git a/src/pickup.c b/src/pickup.c index d68def38d..b32640dbd 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1556,7 +1556,6 @@ struct obj *otmp; int encumber_msg() { - static int oldcap = UNENCUMBERED; int newcap = near_capacity(); if (oldcap < newcap) { From 48c89acef440216c7bec2090b8097f56dcd288e7 Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 22 Nov 2018 15:49:43 -0800 Subject: [PATCH 09/14] Moved petname_used to decl.c --- include/decl.h | 3 +++ src/decl.c | 4 +++- src/dog.c | 1 - 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/decl.h b/include/decl.h index 7fcde0c6c..5e211f053 100644 --- a/include/decl.h +++ b/include/decl.h @@ -192,6 +192,8 @@ E NEARDATA char dogname[]; E NEARDATA char catname[]; E NEARDATA char horsename[]; E char preferred_pet; +E int petname_used; + E const char *occtxt; /* defined when occupation != NULL */ E const char *nomovemsg; E char lock[]; @@ -440,6 +442,7 @@ struct early_opt { /* encumbrance */ E int oldcap; + #undef E #endif /* DECL_H */ diff --git a/src/decl.c b/src/decl.c index c3397a048..10f67f7de 100644 --- a/src/decl.c +++ b/src/decl.c @@ -207,6 +207,7 @@ NEARDATA char dogname[PL_PSIZ] = DUMMY; NEARDATA char catname[PL_PSIZ] = DUMMY; NEARDATA char horsename[PL_PSIZ] = DUMMY; char preferred_pet; /* '\0', 'c', 'd', 'n' (none) */ +int petname_used = 0; /* monsters that went down/up together with @ */ NEARDATA struct monst *mydogs = (struct monst *) 0; /* monsters that are moving to another dungeon level */ @@ -572,7 +573,8 @@ decl_early_init() ZEROARRAYN(dogname, PL_PSIZ); ZEROARRAYN(catname, PL_PSIZ); ZEROARRAYN(horsename, PL_PSIZ); - preferred_pet = 0; + ZERO(preferred_pet); + ZERO(petname_used); ZEROPTR(mydogs); ZEROPTR(migrating_mons); diff --git a/src/dog.c b/src/dog.c index 0d967195e..7c1b62e8b 100644 --- a/src/dog.c +++ b/src/dog.c @@ -160,7 +160,6 @@ makedog() register struct obj *otmp; const char *petname; int pettype; - static int petname_used = 0; if (preferred_pet == 'n') return ((struct monst *) 0); From 0ebe905ad171194bf80544ff6d8ac5eb2bf44506 Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 22 Nov 2018 20:47:22 -0800 Subject: [PATCH 10/14] Initial check in of icontext. --- include/decl.h | 16 ++++++++++++++-- src/decl.c | 19 ++++++++++++++----- src/pickup.c | 6 +++--- sys/share/pcmain.c | 4 +--- sys/winnt/stubs.c | 4 +--- win/win32/winhack.c | 4 +--- 6 files changed, 34 insertions(+), 19 deletions(-) diff --git a/include/decl.h b/include/decl.h index 5e211f053..2cc7f965c 100644 --- a/include/decl.h +++ b/include/decl.h @@ -439,8 +439,20 @@ struct early_opt { boolean valallowed; }; -/* encumbrance */ -E int oldcap; +/* instance_context holds per game instance data that does not need to be + * persisted upon game exit. This game instance data is one of the first + * things initialized during the initialization of the game engine. + * It is initialized with icontext_initial_state found in decl.c */ + +#define PLAYAGAIN + +struct instance_context { + int oldcap; /* encumberance - pickup.c */ +}; + +E struct instance_context icontext; + +E void icontext_init(); #undef E diff --git a/src/decl.c b/src/decl.c index 10f67f7de..edfeb3a60 100644 --- a/src/decl.c +++ b/src/decl.c @@ -215,9 +215,6 @@ NEARDATA struct monst *migrating_mons = (struct monst *) 0; NEARDATA struct mvitals mvitals[NUMMONS]; -/* originally from pickup.c */ -int oldcap = 0; /* encumbrance */ - NEARDATA struct c_color_names c_color_names = { "black", "amber", "golden", "light blue", "red", "green", "silver", "blue", "purple", "white", "orange" @@ -529,8 +526,6 @@ decl_early_init() ZERO(ubirthday); ZERO(urealtime); - ZERO(oldcap); - ZEROARRAY(lastseentyp); ZEROPTR(invent); @@ -612,4 +607,18 @@ decl_early_init() } #endif +const struct instance_context icontext_initial_state = { + 0, /* oldcap - last encumberance in pickup.c */ +}; + +struct instance_context icontext; + +void +icontext_init() +{ + icontext = icontext_initial_state; + + decl_early_init(); +}; + /*decl.c*/ diff --git a/src/pickup.c b/src/pickup.c index b32640dbd..83d5eb273 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1558,7 +1558,7 @@ encumber_msg() { int newcap = near_capacity(); - if (oldcap < newcap) { + if (icontext.oldcap < newcap) { switch (newcap) { case 1: Your("movements are slowed slightly because of your load."); @@ -1576,7 +1576,7 @@ encumber_msg() break; } context.botl = 1; - } else if (oldcap > newcap) { + } else if (icontext.oldcap > newcap) { switch (newcap) { case 0: Your("movements are now unencumbered."); @@ -1595,7 +1595,7 @@ encumber_msg() context.botl = 1; } - oldcap = newcap; + icontext.oldcap = newcap; return newcap; } diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index 9ffbeca51..932ec971e 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -97,9 +97,7 @@ char *argv[]; nethack_enter(argc, argv); -#ifdef PLAYAGAIN - decl_early_init(); -#endif + icontext_init(); sys_early_init(); #if defined(WIN32) && defined(TTY_GRAPHICS) diff --git a/sys/winnt/stubs.c b/sys/winnt/stubs.c index ff3cf5919..9e16c6dce 100644 --- a/sys/winnt/stubs.c +++ b/sys/winnt/stubs.c @@ -37,9 +37,7 @@ char *argv[]; { boolean resuming; -#ifdef PLAYAGAIN - decl_early_init(); -#endif + icontext_init(); sys_early_init(); Strcpy(default_window_sys, "tty"); resuming = pcmain(argc, argv); diff --git a/win/win32/winhack.c b/win/win32/winhack.c index 6db66261e..ef48d6b63 100644 --- a/win/win32/winhack.c +++ b/win/win32/winhack.c @@ -97,9 +97,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, win10_init(); -#ifdef PLAYAGAIN - decl_early_init(); -#endif + icontext_init(); sys_early_init(); /* init applicatio structure */ From 455d2769e084c368912a86c3d30b745b3e165ab3 Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 22 Nov 2018 13:01:58 -0800 Subject: [PATCH 11/14] Initial check-in of icontext work. --- include/config.h | 8 ++ include/decl.h | 18 +++ include/extern.h | 3 + src/decl.c | 275 +++++++++++++++++++++++++++++++++++++++++++ src/dog.c | 1 - src/pickup.c | 7 +- sys/share/pcmain.c | 2 + sys/winnt/stubs.c | 1 + util/lev_main.c | 7 ++ win/share/tile2bmp.c | 7 ++ win/win32/winhack.c | 1 + 11 files changed, 325 insertions(+), 5 deletions(-) diff --git a/include/config.h b/include/config.h index 4f242679a..d4f67e1ac 100644 --- a/include/config.h +++ b/include/config.h @@ -552,6 +552,14 @@ typedef unsigned char uchar; #endif +/* PLAYAGAIN support for allowing the game shell to stay open after the player + * saves or dies. This requires that the game engine can be re-entered to + * start another game. + * + * This support does not include supporting playing another game when + * a panic has occured due to undetermined state the engine is left in after a + * panic */ +/* #define PLAYAGAIN */ /* End of Section 4 */ diff --git a/include/decl.h b/include/decl.h index 992e86ad5..2cc7f965c 100644 --- a/include/decl.h +++ b/include/decl.h @@ -192,6 +192,8 @@ E NEARDATA char dogname[]; E NEARDATA char catname[]; E NEARDATA char horsename[]; E char preferred_pet; +E int petname_used; + E const char *occtxt; /* defined when occupation != NULL */ E const char *nomovemsg; E char lock[]; @@ -437,6 +439,22 @@ struct early_opt { boolean valallowed; }; +/* instance_context holds per game instance data that does not need to be + * persisted upon game exit. This game instance data is one of the first + * things initialized during the initialization of the game engine. + * It is initialized with icontext_initial_state found in decl.c */ + +#define PLAYAGAIN + +struct instance_context { + int oldcap; /* encumberance - pickup.c */ +}; + +E struct instance_context icontext; + +E void icontext_init(); + + #undef E #endif /* DECL_H */ diff --git a/include/extern.h b/include/extern.h index 89910b0bb..d3a251b83 100644 --- a/include/extern.h +++ b/include/extern.h @@ -251,6 +251,9 @@ E void FDECL(destroy_drawbridge, (int, int)); /* ### decl.c ### */ E void NDECL(decl_init); +#ifdef PLAYAGAIN +E void NDECL(decl_early_init); +#endif /* ### detect.c ### */ diff --git a/src/decl.c b/src/decl.c index ffd9ef974..edfeb3a60 100644 --- a/src/decl.c +++ b/src/decl.c @@ -207,6 +207,7 @@ NEARDATA char dogname[PL_PSIZ] = DUMMY; NEARDATA char catname[PL_PSIZ] = DUMMY; NEARDATA char horsename[PL_PSIZ] = DUMMY; char preferred_pet; /* '\0', 'c', 'd', 'n' (none) */ +int petname_used = 0; /* monsters that went down/up together with @ */ NEARDATA struct monst *mydogs = (struct monst *) 0; /* monsters that are moving to another dungeon level */ @@ -284,6 +285,31 @@ char *fqn_prefix_names[PREFIX_COUNT] = { }; #endif +#ifdef PLAYAGAIN +const struct savefile_info default_sfinfo = { +#ifdef NHSTDC + 0x00000000UL +#else + 0x00000000L +#endif +#if defined(COMPRESS) || defined(ZLIB_COMP) + | SFI1_EXTERNALCOMP +#endif +#if defined(ZEROCOMP) + | SFI1_ZEROCOMP +#endif +#if defined(RLECOMP) + | SFI1_RLECOMP +#endif + , +#ifdef NHSTDC + 0x00000000UL, 0x00000000UL +#else + 0x00000000L, 0x00000000L +#endif +}; +#endif + NEARDATA struct savefile_info sfcap = { #ifdef NHSTDC 0x00000000UL @@ -346,4 +372,253 @@ decl_init() return; } +#ifdef PLAYAGAIN + +static boolean s_firstStart = TRUE; + +static boolean +decl_is_block_zero(p, n) +unsigned char * p; +int n; +{ + static unsigned char zeroblock[512] = { 0 }; + unsigned char * sentinel = p + n; + while (p < sentinel) { + int c = (n < sizeof(zeroblock) ? n : sizeof(zeroblock)); + if (memcmp(p, zeroblock, c) != 0) return FALSE; + p += c; + } + return TRUE; +} + +static void +decl_zero_block(p, n) +unsigned char * p; +int n; +{ + nhassert(!s_firstStart || decl_is_block_zero(p, n)); + memset(p, 0, n); +} + +#define ZEROARRAY(x) decl_zero_block((void *) &x[0], 0, sizeof(x)) +#define ZEROARRAYN(x,n) decl_zero_block((void *) &x[0], 0, sizeof(x[0])*(n)) +#define ZERO(x) decl_zero_block((void *) &x, 0, sizeof(x)) +#define ZEROPTR(x) { nhassert(x == NULL); x = NULL; } +#define ZEROPTRNOCHECK(x) { x = NULL; } + +/* decl_early_init() is called when we are starting a game. On first + * start, it validates that global state is in the expected state. + * When called on subsequent starts, it initializes global state to + * expected state. + * + * In the case that of global pointers, on subsequent starts it will + * panic if it finds a non-NULL pointer with the assumption that a + * pointer has leaked. */ + +void +decl_early_init() +{ + hackpid = 0; +#if defined(UNIX) || defined(VMS) + locknum = 0; +#endif +#ifdef DEF_PAGER + catmore = 0; +#endif + + ZEROARRAY(bases); + + multi = 0; + multi_reason = NULL; + nroom = 0; + nsubroom = 0; + occtime = 0; + + x_maze_max = (COLNO - 1) & ~1; + y_maze_max = (ROWNO - 1) & ~1; + + otg_temp = 0; + + ZERO(dungeon_topology); + ZERO(quest_status); + + warn_obj_cnt = 0; + ZEROARRAYN(smeq, MAXNROFROOMS + 1); + doorindex = 0; + save_cm = NULL; + + ZERO(killer); + done_money = 0; + nomovemsg = NULL; + ZEROARRAY(plname); + ZEROARRAY(pl_character); + pl_race = '\0'; + + ZEROARRAY(pl_fruit); + ffruit = NULL; + + ZEROARRAY(tune); + + occtxt = NULL; + + yn_number = 0; + +#if defined(MICRO) || defined(WIN32) + ZEROARRAYN(hackdir, PATHLEN); +#ifdef MICRO + ZEROARRAYN(levels, PATHLEN); +#endif /* MICRO */ +#endif /* MICRO || WIN32 */ + +#ifdef MFLOPPY + ZEROARRAYN(permbones, PATHLEN); + ramdisk = FALSE; + saveprompt = TRUE; +#endif + + ZEROARRAY(level_info); + + ZERO(program_state); + + tbx = 0; + tby = 0; + + ZERO(m_shot); + + ZEROARRAYN(dungeons, MAXDUNGEON); + ZEROPTR(sp_levchn); + ZERO(upstair); + ZERO(dnstair); + ZERO(upladder); + ZERO(dnladder); + ZERO(sstairs); + ZERO(updest); + ZERO(dndest); + ZERO(inv_pos); + + defer_see_monsters = FALSE; + in_mklev = FALSE; + stoned = FALSE; + unweapon = FALSE; + mrg_to_wielded = FALSE; + + in_steed_dismounting = FALSE; + + ZERO(bhitpos); + ZEROARRAY(doors); + + ZEROARRAY(rooms); + subrooms = &rooms[MAXNROFROOMS + 1]; + upstairs_room = NULL; + dnstairs_room = NULL; + sstairs_room = NULL; + + ZERO(level); + ZEROPTR(ftrap); + ZERO(youmonst); + ZERO(context); + ZERO(flags); +#ifdef SYSFLAGS + ZERO(sysflags); +#endif + ZERO(iflags); + ZERO(u); + ZERO(ubirthday); + ZERO(urealtime); + + ZEROARRAY(lastseentyp); + + ZEROPTR(invent); + ZEROPTRNOCHECK(uwep); + ZEROPTRNOCHECK(uarm); + ZEROPTRNOCHECK(uswapwep); + ZEROPTRNOCHECK(uquiver); + ZEROPTRNOCHECK(uarmu); + ZEROPTRNOCHECK(uskin); + ZEROPTRNOCHECK(uarmc); + ZEROPTRNOCHECK(uarmh); + ZEROPTRNOCHECK(uarms); + ZEROPTRNOCHECK(uarmg); + ZEROPTRNOCHECK(uarmf); + ZEROPTRNOCHECK(uamul); + ZEROPTRNOCHECK(uright); + ZEROPTRNOCHECK(uleft); + ZEROPTRNOCHECK(ublindf); + ZEROPTRNOCHECK(uchain); + ZEROPTRNOCHECK(uball); + + ZEROPTR(current_wand); + ZEROPTR(thrownobj); + ZEROPTR(kickedobj); + + ZEROARRAYN(spl_book, MAXSPELL + 1); + + moves = 1; + monstermoves = 1; + + wailmsg = 0L; + + ZEROPTR(migrating_objs); + ZEROPTR(billobjs); + + ZERO(zeroobj); + ZERO(zeromonst); + ZERO(zeroany); + + ZEROARRAYN(dogname, PL_PSIZ); + ZEROARRAYN(catname, PL_PSIZ); + ZEROARRAYN(horsename, PL_PSIZ); + ZERO(preferred_pet); + ZERO(petname_used); + ZEROPTR(mydogs); + ZEROPTR(migrating_mons); + + ZEROARRAY(mvitals); + + ZEROPTR(menu_colorings); + + vision_full_recalc = 0; + viz_array = NULL; + + WIN_MESSAGE = WIN_ERR; +#ifndef STATUS_VIA_WINDOWPORT + WIN_STATUS = WIN_ERR; +#endif + WIN_MAP = WIN_ERR; + WIN_INVEN = WIN_ERR; + + ZEROARRAYN(toplines, TBUFSZ); + ZERO(tc_gbl_data); + ZEROARRAYN(fqn_prefix, PREFIX_COUNT); + + sfcap = default_sfinfo; + sfrestinfo = default_sfinfo; + sfsaveinfo = default_sfinfo; + + ZEROPTR(plinemsg_types); + +#ifdef PANICTRACE + ARGV0 = NULL; +#endif + + nhUse_dummy = 0; + + s_firstStart = FALSE; +} +#endif + +const struct instance_context icontext_initial_state = { + 0, /* oldcap - last encumberance in pickup.c */ +}; + +struct instance_context icontext; + +void +icontext_init() +{ + icontext = icontext_initial_state; + + decl_early_init(); +}; + /*decl.c*/ diff --git a/src/dog.c b/src/dog.c index 0d967195e..7c1b62e8b 100644 --- a/src/dog.c +++ b/src/dog.c @@ -160,7 +160,6 @@ makedog() register struct obj *otmp; const char *petname; int pettype; - static int petname_used = 0; if (preferred_pet == 'n') return ((struct monst *) 0); diff --git a/src/pickup.c b/src/pickup.c index d68def38d..83d5eb273 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1556,10 +1556,9 @@ struct obj *otmp; int encumber_msg() { - static int oldcap = UNENCUMBERED; int newcap = near_capacity(); - if (oldcap < newcap) { + if (icontext.oldcap < newcap) { switch (newcap) { case 1: Your("movements are slowed slightly because of your load."); @@ -1577,7 +1576,7 @@ encumber_msg() break; } context.botl = 1; - } else if (oldcap > newcap) { + } else if (icontext.oldcap > newcap) { switch (newcap) { case 0: Your("movements are now unencumbered."); @@ -1596,7 +1595,7 @@ encumber_msg() context.botl = 1; } - oldcap = newcap; + icontext.oldcap = newcap; return newcap; } diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index 93674ab34..932ec971e 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -97,7 +97,9 @@ char *argv[]; nethack_enter(argc, argv); + icontext_init(); sys_early_init(); + #if defined(WIN32) && defined(TTY_GRAPHICS) Strcpy(default_window_sys, "tty"); #else diff --git a/sys/winnt/stubs.c b/sys/winnt/stubs.c index bb5ad82e4..9e16c6dce 100644 --- a/sys/winnt/stubs.c +++ b/sys/winnt/stubs.c @@ -37,6 +37,7 @@ char *argv[]; { boolean resuming; + icontext_init(); sys_early_init(); Strcpy(default_window_sys, "tty"); resuming = pcmain(argc, argv); diff --git a/util/lev_main.c b/util/lev_main.c index ecf7a444c..729549791 100644 --- a/util/lev_main.c +++ b/util/lev_main.c @@ -1637,4 +1637,11 @@ short ospeed; #endif #endif /* STRICT_REF_DEF */ +/* nhassert_failed is called when an nhassert's condition is false */ +void nhassert_failed(const char * exp, const char * file, int line) +{ + fprintf(stderr, "NHASSERT(%s) in '%s' at line %d\n", exp, file, line); + exit(EXIT_FAILURE); +} + /*lev_main.c*/ diff --git a/win/share/tile2bmp.c b/win/share/tile2bmp.c index ca2c7dd73..6722bbc26 100644 --- a/win/share/tile2bmp.c +++ b/win/share/tile2bmp.c @@ -360,3 +360,10 @@ pixel (*pixels)[TILE_X]; } } } + +/* nhassert_failed is called when an nhassert's condition is false */ +void nhassert_failed(const char * exp, const char * file, int line) +{ + Fprintf(stderr, "NHASSERT(%s) in '%s' at line %d\n", exp, file, line); + exit(EXIT_FAILURE); +} diff --git a/win/win32/winhack.c b/win/win32/winhack.c index 9dcbb4e4b..ef48d6b63 100644 --- a/win/win32/winhack.c +++ b/win/win32/winhack.c @@ -97,6 +97,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, win10_init(); + icontext_init(); sys_early_init(); /* init applicatio structure */ From f0f0dea993054bc00169959f07f06c13b68b37cd Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 22 Nov 2018 21:40:15 -0800 Subject: [PATCH 12/14] check. --- include/config.h | 9 -- include/decl.h | 10 +- include/extern.h | 3 - src/apply.c | 17 +-- src/artifact.c | 35 +++--- src/botl.c | 5 +- src/decl.c | 296 ++--------------------------------------------- src/dog.c | 2 +- src/restore.c | 2 +- 9 files changed, 44 insertions(+), 335 deletions(-) diff --git a/include/config.h b/include/config.h index d4f67e1ac..e0bcdb3d8 100644 --- a/include/config.h +++ b/include/config.h @@ -552,15 +552,6 @@ typedef unsigned char uchar; #endif -/* PLAYAGAIN support for allowing the game shell to stay open after the player - * saves or dies. This requires that the game engine can be re-entered to - * start another game. - * - * This support does not include supporting playing another game when - * a panic has occured due to undetermined state the engine is left in after a - * panic */ -/* #define PLAYAGAIN */ - /* End of Section 4 */ #ifdef TTY_TILES_ESCCODES diff --git a/include/decl.h b/include/decl.h index 2cc7f965c..4716f158c 100644 --- a/include/decl.h +++ b/include/decl.h @@ -192,7 +192,6 @@ E NEARDATA char dogname[]; E NEARDATA char catname[]; E NEARDATA char horsename[]; E char preferred_pet; -E int petname_used; E const char *occtxt; /* defined when occupation != NULL */ E const char *nomovemsg; @@ -444,10 +443,15 @@ struct early_opt { * things initialized during the initialization of the game engine. * It is initialized with icontext_initial_state found in decl.c */ -#define PLAYAGAIN - struct instance_context { int oldcap; /* encumberance - pickup.c */ + int petname_used; /* user preferred pet name has been used - dog.c */ + int jumping_is_magic; /* current jump result of magic - apply.c */ + int polearm_range_min; /* apply.c */ + int polearm_range_max; /* apply.c */ + int spec_dbon_applies; /* coordinate effects from spec_dbon() with + * messages in artifact_hit() - artifact.c */ + int mrank_sz; /* loaded by max_rank_sz - botl.c */ }; E struct instance_context icontext; diff --git a/include/extern.h b/include/extern.h index d3a251b83..89910b0bb 100644 --- a/include/extern.h +++ b/include/extern.h @@ -251,9 +251,6 @@ E void FDECL(destroy_drawbridge, (int, int)); /* ### decl.c ### */ E void NDECL(decl_init); -#ifdef PLAYAGAIN -E void NDECL(decl_early_init); -#endif /* ### detect.c ### */ diff --git a/src/apply.c b/src/apply.c index d202acc77..b4c0270df 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1600,15 +1600,13 @@ boolean showmsg; return TRUE; } -static int jumping_is_magic; - STATIC_OVL boolean get_valid_jump_position(x,y) int x,y; { return (isok(x, y) && (ACCESSIBLE(levl[x][y].typ) || Passes_walls) - && is_valid_jump_pos(x, y, jumping_is_magic, FALSE)); + && is_valid_jump_pos(x, y, icontext.jumping_is_magic, FALSE)); } void @@ -1722,7 +1720,7 @@ int magic; /* 0=Physical, otherwise skill level */ pline("Where do you want to jump?"); cc.x = u.ux; cc.y = u.uy; - jumping_is_magic = magic; + icontext.jumping_is_magic = magic; getpos_sethilite(display_jump_positions, get_valid_jump_position); if (getpos(&cc, TRUE, "the desired position") < 0) return 0; /* user pressed ESC */ @@ -2914,16 +2912,13 @@ int min_range, max_range; return TRUE; } -static int polearm_range_min = -1; -static int polearm_range_max = -1; - STATIC_OVL boolean get_valid_polearm_position(x, y) int x, y; { return (isok(x, y) && ACCESSIBLE(levl[x][y].typ) - && distu(x, y) >= polearm_range_min - && distu(x, y) <= polearm_range_max); + && distu(x, y) >= icontext.polearm_range_min + && distu(x, y) <= icontext.polearm_range_max); } void @@ -2995,8 +2990,8 @@ struct obj *obj; else max_range = 8; /* (P_SKILL(typ) >= P_EXPERT) */ - polearm_range_min = min_range; - polearm_range_max = max_range; + icontext.polearm_range_min = min_range; + icontext.polearm_range_max = max_range; /* Prompt for a location */ pline(where_to_hit); diff --git a/src/artifact.c b/src/artifact.c index 87cbf3b61..a5d090200 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -40,9 +40,6 @@ STATIC_DCL int FDECL(count_surround_traps, (int, int)); of hit points that will fit in a 15 bit integer. */ #define FATAL_DAMAGE_MODIFIER 200 -/* coordinate effects from spec_dbon() with messages in artifact_hit() */ -STATIC_OVL int spec_dbon_applies = 0; - /* flags including which artifacts have already been created */ static boolean artiexist[1 + NROFARTIFACTS + 1]; /* and a discovery list for them (no dummy first entry here) */ @@ -847,15 +844,15 @@ int tmp; if (!weap || (weap->attk.adtyp == AD_PHYS /* check for `NO_ATTK' */ && weap->attk.damn == 0 && weap->attk.damd == 0)) - spec_dbon_applies = FALSE; + icontext.spec_dbon_applies = FALSE; else if (otmp->oartifact == ART_GRIMTOOTH) /* Grimtooth has SPFX settings to warn against elves but we want its damage bonus to apply to all targets, so bypass spec_applies() */ - spec_dbon_applies = TRUE; + icontext.spec_dbon_applies = TRUE; else - spec_dbon_applies = spec_applies(weap, mon); + icontext.spec_dbon_applies = spec_applies(weap, mon); - if (spec_dbon_applies) + if (icontext.spec_dbon_applies) return weap->attk.damd ? rnd((int) weap->attk.damd) : max(tmp, 1); return 0; } @@ -979,14 +976,14 @@ char *hittee; /* target's name: "you" or mon_nam(mdef) */ scare_dieroll /= (1 << (mb->spe / 3)); /* if target successfully resisted the artifact damage bonus, reduce overall likelihood of the assorted special effects */ - if (!spec_dbon_applies) + if (!icontext.spec_dbon_applies) dieroll += 1; /* might stun even when attempting a more severe effect, but in that case it will only happen if the other effect fails; extra damage will apply regardless; 3.4.1: sometimes might just probe even when it hasn't been enchanted */ - do_stun = (max(mb->spe, 0) < rn2(spec_dbon_applies ? 11 : 7)); + do_stun = (max(mb->spe, 0) < rn2(icontext.spec_dbon_applies ? 11 : 7)); /* the special effects also boost physical damage; increments are generally cumulative, but since the stun effect is based on a @@ -1185,12 +1182,12 @@ int dieroll; /* needed for Magicbane and vorpal blades */ if (attacks(AD_FIRE, otmp)) { if (realizes_damage) pline_The("fiery blade %s %s%c", - !spec_dbon_applies + !icontext.spec_dbon_applies ? "hits" : (mdef->data == &mons[PM_WATER_ELEMENTAL]) ? "vaporizes part of" : "burns", - hittee, !spec_dbon_applies ? '.' : '!'); + hittee, !icontext.spec_dbon_applies ? '.' : '!'); if (!rn2(4)) (void) destroy_mitem(mdef, POTION_CLASS, AD_FIRE); if (!rn2(4)) @@ -1204,8 +1201,8 @@ int dieroll; /* needed for Magicbane and vorpal blades */ if (attacks(AD_COLD, otmp)) { if (realizes_damage) pline_The("ice-cold blade %s %s%c", - !spec_dbon_applies ? "hits" : "freezes", hittee, - !spec_dbon_applies ? '.' : '!'); + !icontext.spec_dbon_applies ? "hits" : "freezes", hittee, + !icontext.spec_dbon_applies ? '.' : '!'); if (!rn2(4)) (void) destroy_mitem(mdef, POTION_CLASS, AD_COLD); return realizes_damage; @@ -1213,9 +1210,9 @@ int dieroll; /* needed for Magicbane and vorpal blades */ if (attacks(AD_ELEC, otmp)) { if (realizes_damage) pline_The("massive hammer hits%s %s%c", - !spec_dbon_applies ? "" : "! Lightning strikes", - hittee, !spec_dbon_applies ? '.' : '!'); - if (spec_dbon_applies) + !icontext.spec_dbon_applies ? "" : "! Lightning strikes", + hittee, !icontext.spec_dbon_applies ? '.' : '!'); + if (icontext.spec_dbon_applies) wake_nearto(mdef->mx, mdef->my, 4 * 4); if (!rn2(5)) (void) destroy_mitem(mdef, RING_CLASS, AD_ELEC); @@ -1226,10 +1223,10 @@ int dieroll; /* needed for Magicbane and vorpal blades */ if (attacks(AD_MAGM, otmp)) { if (realizes_damage) pline_The("imaginary widget hits%s %s%c", - !spec_dbon_applies + !icontext.spec_dbon_applies ? "" : "! A hail of magic missiles strikes", - hittee, !spec_dbon_applies ? '.' : '!'); + hittee, !icontext.spec_dbon_applies ? '.' : '!'); return realizes_damage; } @@ -1238,7 +1235,7 @@ int dieroll; /* needed for Magicbane and vorpal blades */ return Mb_hit(magr, mdef, otmp, dmgptr, dieroll, vis, hittee); } - if (!spec_dbon_applies) { + if (!icontext.spec_dbon_applies) { /* since damage bonus didn't apply, nothing more to do; no further attacks have side-effects on inventory */ return FALSE; diff --git a/src/botl.c b/src/botl.c index 4af749105..9256051b3 100644 --- a/src/botl.c +++ b/src/botl.c @@ -11,7 +11,6 @@ extern const char *hu_stat[]; /* defined in eat.c */ const char *const enc_stat[] = { "", "Burdened", "Stressed", "Strained", "Overtaxed", "Overloaded" }; -STATIC_OVL NEARDATA int mrank_sz = 0; /* loaded by max_rank_sz (from u_init) */ STATIC_DCL const char *NDECL(rank); #ifdef STATUS_HILITES STATIC_DCL void NDECL(bot_via_windowport); @@ -65,7 +64,7 @@ do_statusline1() Strcpy(nb = eos(nb), rank()); Sprintf(nb = eos(nb), " "); - i = mrank_sz + 15; + i = icontext.mrank_sz + 15; j = (int) ((nb + 2) - newbot1); /* strlen(newbot1) but less computation */ if ((i - j) > 0) Sprintf(nb = eos(nb), "%*s", i - j, " "); /* pad with spaces */ @@ -346,7 +345,7 @@ max_rank_sz() if (urole.rank[i].f && (r = strlen(urole.rank[i].f)) > maxr) maxr = r; } - mrank_sz = maxr; + icontext.mrank_sz = maxr; return; } diff --git a/src/decl.c b/src/decl.c index edfeb3a60..2a259efaa 100644 --- a/src/decl.c +++ b/src/decl.c @@ -207,7 +207,6 @@ NEARDATA char dogname[PL_PSIZ] = DUMMY; NEARDATA char catname[PL_PSIZ] = DUMMY; NEARDATA char horsename[PL_PSIZ] = DUMMY; char preferred_pet; /* '\0', 'c', 'd', 'n' (none) */ -int petname_used = 0; /* monsters that went down/up together with @ */ NEARDATA struct monst *mydogs = (struct monst *) 0; /* monsters that are moving to another dungeon level */ @@ -285,7 +284,6 @@ char *fqn_prefix_names[PREFIX_COUNT] = { }; #endif -#ifdef PLAYAGAIN const struct savefile_info default_sfinfo = { #ifdef NHSTDC 0x00000000UL @@ -308,53 +306,8 @@ const struct savefile_info default_sfinfo = { 0x00000000L, 0x00000000L #endif }; -#endif -NEARDATA struct savefile_info sfcap = { -#ifdef NHSTDC - 0x00000000UL -#else - 0x00000000L -#endif -#if defined(COMPRESS) || defined(ZLIB_COMP) - | SFI1_EXTERNALCOMP -#endif -#if defined(ZEROCOMP) - | SFI1_ZEROCOMP -#endif -#if defined(RLECOMP) - | SFI1_RLECOMP -#endif - , -#ifdef NHSTDC - 0x00000000UL, 0x00000000UL -#else - 0x00000000L, 0x00000000L -#endif -}; - -NEARDATA struct savefile_info sfrestinfo, sfsaveinfo = { -#ifdef NHSTDC - 0x00000000UL -#else - 0x00000000L -#endif -#if defined(COMPRESS) || defined(ZLIB_COMP) - | SFI1_EXTERNALCOMP -#endif -#if defined(ZEROCOMP) - | SFI1_ZEROCOMP -#endif -#if defined(RLECOMP) - | SFI1_RLECOMP -#endif - , -#ifdef NHSTDC - 0x00000000UL, 0x00000000UL -#else - 0x00000000L, 0x00000000L -#endif -}; +NEARDATA struct savefile_info sfcap, sfrestinfo, sfsaveinfo; struct plinemsg_type *plinemsg_types = (struct plinemsg_type *) 0; @@ -372,243 +325,14 @@ decl_init() return; } -#ifdef PLAYAGAIN - -static boolean s_firstStart = TRUE; - -static boolean -decl_is_block_zero(p, n) -unsigned char * p; -int n; -{ - static unsigned char zeroblock[512] = { 0 }; - unsigned char * sentinel = p + n; - while (p < sentinel) { - int c = (n < sizeof(zeroblock) ? n : sizeof(zeroblock)); - if (memcmp(p, zeroblock, c) != 0) return FALSE; - p += c; - } - return TRUE; -} - -static void -decl_zero_block(p, n) -unsigned char * p; -int n; -{ - nhassert(!s_firstStart || decl_is_block_zero(p, n)); - memset(p, 0, n); -} - -#define ZEROARRAY(x) decl_zero_block((void *) &x[0], 0, sizeof(x)) -#define ZEROARRAYN(x,n) decl_zero_block((void *) &x[0], 0, sizeof(x[0])*(n)) -#define ZERO(x) decl_zero_block((void *) &x, 0, sizeof(x)) -#define ZEROPTR(x) { nhassert(x == NULL); x = NULL; } -#define ZEROPTRNOCHECK(x) { x = NULL; } - -/* decl_early_init() is called when we are starting a game. On first - * start, it validates that global state is in the expected state. - * When called on subsequent starts, it initializes global state to - * expected state. - * - * In the case that of global pointers, on subsequent starts it will - * panic if it finds a non-NULL pointer with the assumption that a - * pointer has leaked. */ - -void -decl_early_init() -{ - hackpid = 0; -#if defined(UNIX) || defined(VMS) - locknum = 0; -#endif -#ifdef DEF_PAGER - catmore = 0; -#endif - - ZEROARRAY(bases); - - multi = 0; - multi_reason = NULL; - nroom = 0; - nsubroom = 0; - occtime = 0; - - x_maze_max = (COLNO - 1) & ~1; - y_maze_max = (ROWNO - 1) & ~1; - - otg_temp = 0; - - ZERO(dungeon_topology); - ZERO(quest_status); - - warn_obj_cnt = 0; - ZEROARRAYN(smeq, MAXNROFROOMS + 1); - doorindex = 0; - save_cm = NULL; - - ZERO(killer); - done_money = 0; - nomovemsg = NULL; - ZEROARRAY(plname); - ZEROARRAY(pl_character); - pl_race = '\0'; - - ZEROARRAY(pl_fruit); - ffruit = NULL; - - ZEROARRAY(tune); - - occtxt = NULL; - - yn_number = 0; - -#if defined(MICRO) || defined(WIN32) - ZEROARRAYN(hackdir, PATHLEN); -#ifdef MICRO - ZEROARRAYN(levels, PATHLEN); -#endif /* MICRO */ -#endif /* MICRO || WIN32 */ - -#ifdef MFLOPPY - ZEROARRAYN(permbones, PATHLEN); - ramdisk = FALSE; - saveprompt = TRUE; -#endif - - ZEROARRAY(level_info); - - ZERO(program_state); - - tbx = 0; - tby = 0; - - ZERO(m_shot); - - ZEROARRAYN(dungeons, MAXDUNGEON); - ZEROPTR(sp_levchn); - ZERO(upstair); - ZERO(dnstair); - ZERO(upladder); - ZERO(dnladder); - ZERO(sstairs); - ZERO(updest); - ZERO(dndest); - ZERO(inv_pos); - - defer_see_monsters = FALSE; - in_mklev = FALSE; - stoned = FALSE; - unweapon = FALSE; - mrg_to_wielded = FALSE; - - in_steed_dismounting = FALSE; - - ZERO(bhitpos); - ZEROARRAY(doors); - - ZEROARRAY(rooms); - subrooms = &rooms[MAXNROFROOMS + 1]; - upstairs_room = NULL; - dnstairs_room = NULL; - sstairs_room = NULL; - - ZERO(level); - ZEROPTR(ftrap); - ZERO(youmonst); - ZERO(context); - ZERO(flags); -#ifdef SYSFLAGS - ZERO(sysflags); -#endif - ZERO(iflags); - ZERO(u); - ZERO(ubirthday); - ZERO(urealtime); - - ZEROARRAY(lastseentyp); - - ZEROPTR(invent); - ZEROPTRNOCHECK(uwep); - ZEROPTRNOCHECK(uarm); - ZEROPTRNOCHECK(uswapwep); - ZEROPTRNOCHECK(uquiver); - ZEROPTRNOCHECK(uarmu); - ZEROPTRNOCHECK(uskin); - ZEROPTRNOCHECK(uarmc); - ZEROPTRNOCHECK(uarmh); - ZEROPTRNOCHECK(uarms); - ZEROPTRNOCHECK(uarmg); - ZEROPTRNOCHECK(uarmf); - ZEROPTRNOCHECK(uamul); - ZEROPTRNOCHECK(uright); - ZEROPTRNOCHECK(uleft); - ZEROPTRNOCHECK(ublindf); - ZEROPTRNOCHECK(uchain); - ZEROPTRNOCHECK(uball); - - ZEROPTR(current_wand); - ZEROPTR(thrownobj); - ZEROPTR(kickedobj); - - ZEROARRAYN(spl_book, MAXSPELL + 1); - - moves = 1; - monstermoves = 1; - - wailmsg = 0L; - - ZEROPTR(migrating_objs); - ZEROPTR(billobjs); - - ZERO(zeroobj); - ZERO(zeromonst); - ZERO(zeroany); - - ZEROARRAYN(dogname, PL_PSIZ); - ZEROARRAYN(catname, PL_PSIZ); - ZEROARRAYN(horsename, PL_PSIZ); - ZERO(preferred_pet); - ZERO(petname_used); - ZEROPTR(mydogs); - ZEROPTR(migrating_mons); - - ZEROARRAY(mvitals); - - ZEROPTR(menu_colorings); - - vision_full_recalc = 0; - viz_array = NULL; - - WIN_MESSAGE = WIN_ERR; -#ifndef STATUS_VIA_WINDOWPORT - WIN_STATUS = WIN_ERR; -#endif - WIN_MAP = WIN_ERR; - WIN_INVEN = WIN_ERR; - - ZEROARRAYN(toplines, TBUFSZ); - ZERO(tc_gbl_data); - ZEROARRAYN(fqn_prefix, PREFIX_COUNT); - - sfcap = default_sfinfo; - sfrestinfo = default_sfinfo; - sfsaveinfo = default_sfinfo; - - ZEROPTR(plinemsg_types); - -#ifdef PANICTRACE - ARGV0 = NULL; -#endif - - nhUse_dummy = 0; - - s_firstStart = FALSE; -} -#endif - const struct instance_context icontext_initial_state = { - 0, /* oldcap - last encumberance in pickup.c */ + 0, /* oldcap - last encumberance in pickup.c */ + 0, /* petname_used - dog.c */ + 0, /* jumping_is_magic - apply.c */ + -1, /* polearm_range_min - apply.c */ + -1, /* polearm_range_max - apply.c */ + 0, /* spec_dbon_applies - artifact.c */ + 0, /* mrank_sz - botl.c */ }; struct instance_context icontext; @@ -618,7 +342,9 @@ icontext_init() { icontext = icontext_initial_state; - decl_early_init(); + sfcap = default_sfinfo; + sfrestinfo = default_sfinfo; + sfsaveinfo = default_sfinfo; }; /*decl.c*/ diff --git a/src/dog.c b/src/dog.c index 7c1b62e8b..79e6b781f 100644 --- a/src/dog.c +++ b/src/dog.c @@ -197,7 +197,7 @@ makedog() put_saddle_on_mon(otmp, mtmp); } - if (!petname_used++ && *petname) + if (!icontext.petname_used++ && *petname) mtmp = christen_monst(mtmp, petname); initedog(mtmp); diff --git a/src/restore.c b/src/restore.c index f26379967..557cb3219 100644 --- a/src/restore.c +++ b/src/restore.c @@ -899,7 +899,7 @@ register int fd; #ifdef MFLOPPY gameDiskPrompt(); #endif - max_rank_sz(); /* to recompute mrank_sz (botl.c) */ + max_rank_sz(); /* to recompute icontext.mrank_sz (botl.c) */ /* take care of iron ball & chain */ for (otmp = fobj; otmp; otmp = otmp->nobj) if (otmp->owornmask) From f8ab311e3d84e24d8f6c10972c2f37e0647fa7ca Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 22 Nov 2018 21:55:03 -0800 Subject: [PATCH 13/14] Fixed nocreate. --- include/decl.h | 4 ++++ src/decl.c | 4 ++++ src/u_init.c | 21 ++++++++------------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/include/decl.h b/include/decl.h index 4716f158c..49bd34d2e 100644 --- a/include/decl.h +++ b/include/decl.h @@ -452,6 +452,10 @@ struct instance_context { int spec_dbon_applies; /* coordinate effects from spec_dbon() with * messages in artifact_hit() - artifact.c */ int mrank_sz; /* loaded by max_rank_sz - botl.c */ + short nocreate; /* ini_inv() - u_init.c = STRANGE_OBJECT */ + short nocreate2; /* ini_inv() - u_init.c = STRANGE_OBJECT */ + short nocreate3; /* ini_inv() - u_init.c = STRANGE_OBJECT */ + short nocreate4; /* ini_inv() - u_init.c = STRANGE_OBJECT */ }; E struct instance_context icontext; diff --git a/src/decl.c b/src/decl.c index 2a259efaa..2f52fc41f 100644 --- a/src/decl.c +++ b/src/decl.c @@ -333,6 +333,10 @@ const struct instance_context icontext_initial_state = { -1, /* polearm_range_max - apply.c */ 0, /* spec_dbon_applies - artifact.c */ 0, /* mrank_sz - botl.c */ + STRANGE_OBJECT, /* nocreate - ini_inv() in u_init.c */ + STRANGE_OBJECT, /* nocreate2 - ini_inv() in u_init.c */ + STRANGE_OBJECT, /* nocreate3 - ini_inv() in u_init.c */ + STRANGE_OBJECT, /* nocreate4 - ini_inv() in u_init.c */ }; struct instance_context icontext; diff --git a/src/u_init.c b/src/u_init.c index 71da5a84a..9d38214ed 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -974,11 +974,6 @@ register struct trobj *trop; struct obj *obj; int otyp, i; - NEARDATA short nocreate = STRANGE_OBJECT; - NEARDATA short nocreate2 = STRANGE_OBJECT; - NEARDATA short nocreate3 = STRANGE_OBJECT; - NEARDATA short nocreate4 = STRANGE_OBJECT; - while (trop->trclass) { otyp = (int) trop->trotyp; if (otyp != UNDEF_TYP) { @@ -996,9 +991,9 @@ register struct trobj *trop; */ obj = mkobj(trop->trclass, FALSE); otyp = obj->otyp; - while (otyp == WAN_WISHING || otyp == nocreate - || otyp == nocreate2 || otyp == nocreate3 - || otyp == nocreate4 || otyp == RIN_LEVITATION + while (otyp == WAN_WISHING || otyp == icontext.nocreate + || otyp == icontext.nocreate2 || otyp == icontext.nocreate3 + || otyp == icontext.nocreate4 || otyp == RIN_LEVITATION /* 'useless' items */ || otyp == POT_HALLUCINATION || otyp == POT_ACID @@ -1040,16 +1035,16 @@ register struct trobj *trop; case WAN_POLYMORPH: case RIN_POLYMORPH: case POT_POLYMORPH: - nocreate = RIN_POLYMORPH_CONTROL; + icontext.nocreate = RIN_POLYMORPH_CONTROL; break; case RIN_POLYMORPH_CONTROL: - nocreate = RIN_POLYMORPH; - nocreate2 = SPE_POLYMORPH; - nocreate3 = POT_POLYMORPH; + icontext.nocreate = RIN_POLYMORPH; + icontext.nocreate2 = SPE_POLYMORPH; + icontext.nocreate3 = POT_POLYMORPH; } /* Don't have 2 of the same ring or spellbook */ if (obj->oclass == RING_CLASS || obj->oclass == SPBOOK_CLASS) - nocreate4 = otyp; + icontext.nocreate4 = otyp; } if (urace.malenum != PM_HUMAN) { From f305d1ab6c1fe0bdabe8c106f701311942a1074c Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 22 Nov 2018 21:40:15 -0800 Subject: [PATCH 14/14] Fixed nocreate. --- include/config.h | 9 -- include/decl.h | 14 ++- include/extern.h | 3 - src/apply.c | 17 +-- src/artifact.c | 35 +++--- src/botl.c | 5 +- src/decl.c | 300 +++-------------------------------------------- src/dog.c | 2 +- src/restore.c | 2 +- src/u_init.c | 21 ++-- 10 files changed, 60 insertions(+), 348 deletions(-) diff --git a/include/config.h b/include/config.h index d4f67e1ac..e0bcdb3d8 100644 --- a/include/config.h +++ b/include/config.h @@ -552,15 +552,6 @@ typedef unsigned char uchar; #endif -/* PLAYAGAIN support for allowing the game shell to stay open after the player - * saves or dies. This requires that the game engine can be re-entered to - * start another game. - * - * This support does not include supporting playing another game when - * a panic has occured due to undetermined state the engine is left in after a - * panic */ -/* #define PLAYAGAIN */ - /* End of Section 4 */ #ifdef TTY_TILES_ESCCODES diff --git a/include/decl.h b/include/decl.h index 2cc7f965c..49bd34d2e 100644 --- a/include/decl.h +++ b/include/decl.h @@ -192,7 +192,6 @@ E NEARDATA char dogname[]; E NEARDATA char catname[]; E NEARDATA char horsename[]; E char preferred_pet; -E int petname_used; E const char *occtxt; /* defined when occupation != NULL */ E const char *nomovemsg; @@ -444,10 +443,19 @@ struct early_opt { * things initialized during the initialization of the game engine. * It is initialized with icontext_initial_state found in decl.c */ -#define PLAYAGAIN - struct instance_context { int oldcap; /* encumberance - pickup.c */ + int petname_used; /* user preferred pet name has been used - dog.c */ + int jumping_is_magic; /* current jump result of magic - apply.c */ + int polearm_range_min; /* apply.c */ + int polearm_range_max; /* apply.c */ + int spec_dbon_applies; /* coordinate effects from spec_dbon() with + * messages in artifact_hit() - artifact.c */ + int mrank_sz; /* loaded by max_rank_sz - botl.c */ + short nocreate; /* ini_inv() - u_init.c = STRANGE_OBJECT */ + short nocreate2; /* ini_inv() - u_init.c = STRANGE_OBJECT */ + short nocreate3; /* ini_inv() - u_init.c = STRANGE_OBJECT */ + short nocreate4; /* ini_inv() - u_init.c = STRANGE_OBJECT */ }; E struct instance_context icontext; diff --git a/include/extern.h b/include/extern.h index d3a251b83..89910b0bb 100644 --- a/include/extern.h +++ b/include/extern.h @@ -251,9 +251,6 @@ E void FDECL(destroy_drawbridge, (int, int)); /* ### decl.c ### */ E void NDECL(decl_init); -#ifdef PLAYAGAIN -E void NDECL(decl_early_init); -#endif /* ### detect.c ### */ diff --git a/src/apply.c b/src/apply.c index d202acc77..b4c0270df 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1600,15 +1600,13 @@ boolean showmsg; return TRUE; } -static int jumping_is_magic; - STATIC_OVL boolean get_valid_jump_position(x,y) int x,y; { return (isok(x, y) && (ACCESSIBLE(levl[x][y].typ) || Passes_walls) - && is_valid_jump_pos(x, y, jumping_is_magic, FALSE)); + && is_valid_jump_pos(x, y, icontext.jumping_is_magic, FALSE)); } void @@ -1722,7 +1720,7 @@ int magic; /* 0=Physical, otherwise skill level */ pline("Where do you want to jump?"); cc.x = u.ux; cc.y = u.uy; - jumping_is_magic = magic; + icontext.jumping_is_magic = magic; getpos_sethilite(display_jump_positions, get_valid_jump_position); if (getpos(&cc, TRUE, "the desired position") < 0) return 0; /* user pressed ESC */ @@ -2914,16 +2912,13 @@ int min_range, max_range; return TRUE; } -static int polearm_range_min = -1; -static int polearm_range_max = -1; - STATIC_OVL boolean get_valid_polearm_position(x, y) int x, y; { return (isok(x, y) && ACCESSIBLE(levl[x][y].typ) - && distu(x, y) >= polearm_range_min - && distu(x, y) <= polearm_range_max); + && distu(x, y) >= icontext.polearm_range_min + && distu(x, y) <= icontext.polearm_range_max); } void @@ -2995,8 +2990,8 @@ struct obj *obj; else max_range = 8; /* (P_SKILL(typ) >= P_EXPERT) */ - polearm_range_min = min_range; - polearm_range_max = max_range; + icontext.polearm_range_min = min_range; + icontext.polearm_range_max = max_range; /* Prompt for a location */ pline(where_to_hit); diff --git a/src/artifact.c b/src/artifact.c index 87cbf3b61..a5d090200 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -40,9 +40,6 @@ STATIC_DCL int FDECL(count_surround_traps, (int, int)); of hit points that will fit in a 15 bit integer. */ #define FATAL_DAMAGE_MODIFIER 200 -/* coordinate effects from spec_dbon() with messages in artifact_hit() */ -STATIC_OVL int spec_dbon_applies = 0; - /* flags including which artifacts have already been created */ static boolean artiexist[1 + NROFARTIFACTS + 1]; /* and a discovery list for them (no dummy first entry here) */ @@ -847,15 +844,15 @@ int tmp; if (!weap || (weap->attk.adtyp == AD_PHYS /* check for `NO_ATTK' */ && weap->attk.damn == 0 && weap->attk.damd == 0)) - spec_dbon_applies = FALSE; + icontext.spec_dbon_applies = FALSE; else if (otmp->oartifact == ART_GRIMTOOTH) /* Grimtooth has SPFX settings to warn against elves but we want its damage bonus to apply to all targets, so bypass spec_applies() */ - spec_dbon_applies = TRUE; + icontext.spec_dbon_applies = TRUE; else - spec_dbon_applies = spec_applies(weap, mon); + icontext.spec_dbon_applies = spec_applies(weap, mon); - if (spec_dbon_applies) + if (icontext.spec_dbon_applies) return weap->attk.damd ? rnd((int) weap->attk.damd) : max(tmp, 1); return 0; } @@ -979,14 +976,14 @@ char *hittee; /* target's name: "you" or mon_nam(mdef) */ scare_dieroll /= (1 << (mb->spe / 3)); /* if target successfully resisted the artifact damage bonus, reduce overall likelihood of the assorted special effects */ - if (!spec_dbon_applies) + if (!icontext.spec_dbon_applies) dieroll += 1; /* might stun even when attempting a more severe effect, but in that case it will only happen if the other effect fails; extra damage will apply regardless; 3.4.1: sometimes might just probe even when it hasn't been enchanted */ - do_stun = (max(mb->spe, 0) < rn2(spec_dbon_applies ? 11 : 7)); + do_stun = (max(mb->spe, 0) < rn2(icontext.spec_dbon_applies ? 11 : 7)); /* the special effects also boost physical damage; increments are generally cumulative, but since the stun effect is based on a @@ -1185,12 +1182,12 @@ int dieroll; /* needed for Magicbane and vorpal blades */ if (attacks(AD_FIRE, otmp)) { if (realizes_damage) pline_The("fiery blade %s %s%c", - !spec_dbon_applies + !icontext.spec_dbon_applies ? "hits" : (mdef->data == &mons[PM_WATER_ELEMENTAL]) ? "vaporizes part of" : "burns", - hittee, !spec_dbon_applies ? '.' : '!'); + hittee, !icontext.spec_dbon_applies ? '.' : '!'); if (!rn2(4)) (void) destroy_mitem(mdef, POTION_CLASS, AD_FIRE); if (!rn2(4)) @@ -1204,8 +1201,8 @@ int dieroll; /* needed for Magicbane and vorpal blades */ if (attacks(AD_COLD, otmp)) { if (realizes_damage) pline_The("ice-cold blade %s %s%c", - !spec_dbon_applies ? "hits" : "freezes", hittee, - !spec_dbon_applies ? '.' : '!'); + !icontext.spec_dbon_applies ? "hits" : "freezes", hittee, + !icontext.spec_dbon_applies ? '.' : '!'); if (!rn2(4)) (void) destroy_mitem(mdef, POTION_CLASS, AD_COLD); return realizes_damage; @@ -1213,9 +1210,9 @@ int dieroll; /* needed for Magicbane and vorpal blades */ if (attacks(AD_ELEC, otmp)) { if (realizes_damage) pline_The("massive hammer hits%s %s%c", - !spec_dbon_applies ? "" : "! Lightning strikes", - hittee, !spec_dbon_applies ? '.' : '!'); - if (spec_dbon_applies) + !icontext.spec_dbon_applies ? "" : "! Lightning strikes", + hittee, !icontext.spec_dbon_applies ? '.' : '!'); + if (icontext.spec_dbon_applies) wake_nearto(mdef->mx, mdef->my, 4 * 4); if (!rn2(5)) (void) destroy_mitem(mdef, RING_CLASS, AD_ELEC); @@ -1226,10 +1223,10 @@ int dieroll; /* needed for Magicbane and vorpal blades */ if (attacks(AD_MAGM, otmp)) { if (realizes_damage) pline_The("imaginary widget hits%s %s%c", - !spec_dbon_applies + !icontext.spec_dbon_applies ? "" : "! A hail of magic missiles strikes", - hittee, !spec_dbon_applies ? '.' : '!'); + hittee, !icontext.spec_dbon_applies ? '.' : '!'); return realizes_damage; } @@ -1238,7 +1235,7 @@ int dieroll; /* needed for Magicbane and vorpal blades */ return Mb_hit(magr, mdef, otmp, dmgptr, dieroll, vis, hittee); } - if (!spec_dbon_applies) { + if (!icontext.spec_dbon_applies) { /* since damage bonus didn't apply, nothing more to do; no further attacks have side-effects on inventory */ return FALSE; diff --git a/src/botl.c b/src/botl.c index 4af749105..9256051b3 100644 --- a/src/botl.c +++ b/src/botl.c @@ -11,7 +11,6 @@ extern const char *hu_stat[]; /* defined in eat.c */ const char *const enc_stat[] = { "", "Burdened", "Stressed", "Strained", "Overtaxed", "Overloaded" }; -STATIC_OVL NEARDATA int mrank_sz = 0; /* loaded by max_rank_sz (from u_init) */ STATIC_DCL const char *NDECL(rank); #ifdef STATUS_HILITES STATIC_DCL void NDECL(bot_via_windowport); @@ -65,7 +64,7 @@ do_statusline1() Strcpy(nb = eos(nb), rank()); Sprintf(nb = eos(nb), " "); - i = mrank_sz + 15; + i = icontext.mrank_sz + 15; j = (int) ((nb + 2) - newbot1); /* strlen(newbot1) but less computation */ if ((i - j) > 0) Sprintf(nb = eos(nb), "%*s", i - j, " "); /* pad with spaces */ @@ -346,7 +345,7 @@ max_rank_sz() if (urole.rank[i].f && (r = strlen(urole.rank[i].f)) > maxr) maxr = r; } - mrank_sz = maxr; + icontext.mrank_sz = maxr; return; } diff --git a/src/decl.c b/src/decl.c index edfeb3a60..2f52fc41f 100644 --- a/src/decl.c +++ b/src/decl.c @@ -207,7 +207,6 @@ NEARDATA char dogname[PL_PSIZ] = DUMMY; NEARDATA char catname[PL_PSIZ] = DUMMY; NEARDATA char horsename[PL_PSIZ] = DUMMY; char preferred_pet; /* '\0', 'c', 'd', 'n' (none) */ -int petname_used = 0; /* monsters that went down/up together with @ */ NEARDATA struct monst *mydogs = (struct monst *) 0; /* monsters that are moving to another dungeon level */ @@ -285,7 +284,6 @@ char *fqn_prefix_names[PREFIX_COUNT] = { }; #endif -#ifdef PLAYAGAIN const struct savefile_info default_sfinfo = { #ifdef NHSTDC 0x00000000UL @@ -308,53 +306,8 @@ const struct savefile_info default_sfinfo = { 0x00000000L, 0x00000000L #endif }; -#endif -NEARDATA struct savefile_info sfcap = { -#ifdef NHSTDC - 0x00000000UL -#else - 0x00000000L -#endif -#if defined(COMPRESS) || defined(ZLIB_COMP) - | SFI1_EXTERNALCOMP -#endif -#if defined(ZEROCOMP) - | SFI1_ZEROCOMP -#endif -#if defined(RLECOMP) - | SFI1_RLECOMP -#endif - , -#ifdef NHSTDC - 0x00000000UL, 0x00000000UL -#else - 0x00000000L, 0x00000000L -#endif -}; - -NEARDATA struct savefile_info sfrestinfo, sfsaveinfo = { -#ifdef NHSTDC - 0x00000000UL -#else - 0x00000000L -#endif -#if defined(COMPRESS) || defined(ZLIB_COMP) - | SFI1_EXTERNALCOMP -#endif -#if defined(ZEROCOMP) - | SFI1_ZEROCOMP -#endif -#if defined(RLECOMP) - | SFI1_RLECOMP -#endif - , -#ifdef NHSTDC - 0x00000000UL, 0x00000000UL -#else - 0x00000000L, 0x00000000L -#endif -}; +NEARDATA struct savefile_info sfcap, sfrestinfo, sfsaveinfo; struct plinemsg_type *plinemsg_types = (struct plinemsg_type *) 0; @@ -372,243 +325,18 @@ decl_init() return; } -#ifdef PLAYAGAIN - -static boolean s_firstStart = TRUE; - -static boolean -decl_is_block_zero(p, n) -unsigned char * p; -int n; -{ - static unsigned char zeroblock[512] = { 0 }; - unsigned char * sentinel = p + n; - while (p < sentinel) { - int c = (n < sizeof(zeroblock) ? n : sizeof(zeroblock)); - if (memcmp(p, zeroblock, c) != 0) return FALSE; - p += c; - } - return TRUE; -} - -static void -decl_zero_block(p, n) -unsigned char * p; -int n; -{ - nhassert(!s_firstStart || decl_is_block_zero(p, n)); - memset(p, 0, n); -} - -#define ZEROARRAY(x) decl_zero_block((void *) &x[0], 0, sizeof(x)) -#define ZEROARRAYN(x,n) decl_zero_block((void *) &x[0], 0, sizeof(x[0])*(n)) -#define ZERO(x) decl_zero_block((void *) &x, 0, sizeof(x)) -#define ZEROPTR(x) { nhassert(x == NULL); x = NULL; } -#define ZEROPTRNOCHECK(x) { x = NULL; } - -/* decl_early_init() is called when we are starting a game. On first - * start, it validates that global state is in the expected state. - * When called on subsequent starts, it initializes global state to - * expected state. - * - * In the case that of global pointers, on subsequent starts it will - * panic if it finds a non-NULL pointer with the assumption that a - * pointer has leaked. */ - -void -decl_early_init() -{ - hackpid = 0; -#if defined(UNIX) || defined(VMS) - locknum = 0; -#endif -#ifdef DEF_PAGER - catmore = 0; -#endif - - ZEROARRAY(bases); - - multi = 0; - multi_reason = NULL; - nroom = 0; - nsubroom = 0; - occtime = 0; - - x_maze_max = (COLNO - 1) & ~1; - y_maze_max = (ROWNO - 1) & ~1; - - otg_temp = 0; - - ZERO(dungeon_topology); - ZERO(quest_status); - - warn_obj_cnt = 0; - ZEROARRAYN(smeq, MAXNROFROOMS + 1); - doorindex = 0; - save_cm = NULL; - - ZERO(killer); - done_money = 0; - nomovemsg = NULL; - ZEROARRAY(plname); - ZEROARRAY(pl_character); - pl_race = '\0'; - - ZEROARRAY(pl_fruit); - ffruit = NULL; - - ZEROARRAY(tune); - - occtxt = NULL; - - yn_number = 0; - -#if defined(MICRO) || defined(WIN32) - ZEROARRAYN(hackdir, PATHLEN); -#ifdef MICRO - ZEROARRAYN(levels, PATHLEN); -#endif /* MICRO */ -#endif /* MICRO || WIN32 */ - -#ifdef MFLOPPY - ZEROARRAYN(permbones, PATHLEN); - ramdisk = FALSE; - saveprompt = TRUE; -#endif - - ZEROARRAY(level_info); - - ZERO(program_state); - - tbx = 0; - tby = 0; - - ZERO(m_shot); - - ZEROARRAYN(dungeons, MAXDUNGEON); - ZEROPTR(sp_levchn); - ZERO(upstair); - ZERO(dnstair); - ZERO(upladder); - ZERO(dnladder); - ZERO(sstairs); - ZERO(updest); - ZERO(dndest); - ZERO(inv_pos); - - defer_see_monsters = FALSE; - in_mklev = FALSE; - stoned = FALSE; - unweapon = FALSE; - mrg_to_wielded = FALSE; - - in_steed_dismounting = FALSE; - - ZERO(bhitpos); - ZEROARRAY(doors); - - ZEROARRAY(rooms); - subrooms = &rooms[MAXNROFROOMS + 1]; - upstairs_room = NULL; - dnstairs_room = NULL; - sstairs_room = NULL; - - ZERO(level); - ZEROPTR(ftrap); - ZERO(youmonst); - ZERO(context); - ZERO(flags); -#ifdef SYSFLAGS - ZERO(sysflags); -#endif - ZERO(iflags); - ZERO(u); - ZERO(ubirthday); - ZERO(urealtime); - - ZEROARRAY(lastseentyp); - - ZEROPTR(invent); - ZEROPTRNOCHECK(uwep); - ZEROPTRNOCHECK(uarm); - ZEROPTRNOCHECK(uswapwep); - ZEROPTRNOCHECK(uquiver); - ZEROPTRNOCHECK(uarmu); - ZEROPTRNOCHECK(uskin); - ZEROPTRNOCHECK(uarmc); - ZEROPTRNOCHECK(uarmh); - ZEROPTRNOCHECK(uarms); - ZEROPTRNOCHECK(uarmg); - ZEROPTRNOCHECK(uarmf); - ZEROPTRNOCHECK(uamul); - ZEROPTRNOCHECK(uright); - ZEROPTRNOCHECK(uleft); - ZEROPTRNOCHECK(ublindf); - ZEROPTRNOCHECK(uchain); - ZEROPTRNOCHECK(uball); - - ZEROPTR(current_wand); - ZEROPTR(thrownobj); - ZEROPTR(kickedobj); - - ZEROARRAYN(spl_book, MAXSPELL + 1); - - moves = 1; - monstermoves = 1; - - wailmsg = 0L; - - ZEROPTR(migrating_objs); - ZEROPTR(billobjs); - - ZERO(zeroobj); - ZERO(zeromonst); - ZERO(zeroany); - - ZEROARRAYN(dogname, PL_PSIZ); - ZEROARRAYN(catname, PL_PSIZ); - ZEROARRAYN(horsename, PL_PSIZ); - ZERO(preferred_pet); - ZERO(petname_used); - ZEROPTR(mydogs); - ZEROPTR(migrating_mons); - - ZEROARRAY(mvitals); - - ZEROPTR(menu_colorings); - - vision_full_recalc = 0; - viz_array = NULL; - - WIN_MESSAGE = WIN_ERR; -#ifndef STATUS_VIA_WINDOWPORT - WIN_STATUS = WIN_ERR; -#endif - WIN_MAP = WIN_ERR; - WIN_INVEN = WIN_ERR; - - ZEROARRAYN(toplines, TBUFSZ); - ZERO(tc_gbl_data); - ZEROARRAYN(fqn_prefix, PREFIX_COUNT); - - sfcap = default_sfinfo; - sfrestinfo = default_sfinfo; - sfsaveinfo = default_sfinfo; - - ZEROPTR(plinemsg_types); - -#ifdef PANICTRACE - ARGV0 = NULL; -#endif - - nhUse_dummy = 0; - - s_firstStart = FALSE; -} -#endif - const struct instance_context icontext_initial_state = { - 0, /* oldcap - last encumberance in pickup.c */ + 0, /* oldcap - last encumberance in pickup.c */ + 0, /* petname_used - dog.c */ + 0, /* jumping_is_magic - apply.c */ + -1, /* polearm_range_min - apply.c */ + -1, /* polearm_range_max - apply.c */ + 0, /* spec_dbon_applies - artifact.c */ + 0, /* mrank_sz - botl.c */ + STRANGE_OBJECT, /* nocreate - ini_inv() in u_init.c */ + STRANGE_OBJECT, /* nocreate2 - ini_inv() in u_init.c */ + STRANGE_OBJECT, /* nocreate3 - ini_inv() in u_init.c */ + STRANGE_OBJECT, /* nocreate4 - ini_inv() in u_init.c */ }; struct instance_context icontext; @@ -618,7 +346,9 @@ icontext_init() { icontext = icontext_initial_state; - decl_early_init(); + sfcap = default_sfinfo; + sfrestinfo = default_sfinfo; + sfsaveinfo = default_sfinfo; }; /*decl.c*/ diff --git a/src/dog.c b/src/dog.c index 7c1b62e8b..79e6b781f 100644 --- a/src/dog.c +++ b/src/dog.c @@ -197,7 +197,7 @@ makedog() put_saddle_on_mon(otmp, mtmp); } - if (!petname_used++ && *petname) + if (!icontext.petname_used++ && *petname) mtmp = christen_monst(mtmp, petname); initedog(mtmp); diff --git a/src/restore.c b/src/restore.c index f26379967..557cb3219 100644 --- a/src/restore.c +++ b/src/restore.c @@ -899,7 +899,7 @@ register int fd; #ifdef MFLOPPY gameDiskPrompt(); #endif - max_rank_sz(); /* to recompute mrank_sz (botl.c) */ + max_rank_sz(); /* to recompute icontext.mrank_sz (botl.c) */ /* take care of iron ball & chain */ for (otmp = fobj; otmp; otmp = otmp->nobj) if (otmp->owornmask) diff --git a/src/u_init.c b/src/u_init.c index 71da5a84a..9d38214ed 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -974,11 +974,6 @@ register struct trobj *trop; struct obj *obj; int otyp, i; - NEARDATA short nocreate = STRANGE_OBJECT; - NEARDATA short nocreate2 = STRANGE_OBJECT; - NEARDATA short nocreate3 = STRANGE_OBJECT; - NEARDATA short nocreate4 = STRANGE_OBJECT; - while (trop->trclass) { otyp = (int) trop->trotyp; if (otyp != UNDEF_TYP) { @@ -996,9 +991,9 @@ register struct trobj *trop; */ obj = mkobj(trop->trclass, FALSE); otyp = obj->otyp; - while (otyp == WAN_WISHING || otyp == nocreate - || otyp == nocreate2 || otyp == nocreate3 - || otyp == nocreate4 || otyp == RIN_LEVITATION + while (otyp == WAN_WISHING || otyp == icontext.nocreate + || otyp == icontext.nocreate2 || otyp == icontext.nocreate3 + || otyp == icontext.nocreate4 || otyp == RIN_LEVITATION /* 'useless' items */ || otyp == POT_HALLUCINATION || otyp == POT_ACID @@ -1040,16 +1035,16 @@ register struct trobj *trop; case WAN_POLYMORPH: case RIN_POLYMORPH: case POT_POLYMORPH: - nocreate = RIN_POLYMORPH_CONTROL; + icontext.nocreate = RIN_POLYMORPH_CONTROL; break; case RIN_POLYMORPH_CONTROL: - nocreate = RIN_POLYMORPH; - nocreate2 = SPE_POLYMORPH; - nocreate3 = POT_POLYMORPH; + icontext.nocreate = RIN_POLYMORPH; + icontext.nocreate2 = SPE_POLYMORPH; + icontext.nocreate3 = POT_POLYMORPH; } /* Don't have 2 of the same ring or spellbook */ if (obj->oclass == RING_CLASS || obj->oclass == SPBOOK_CLASS) - nocreate4 = otyp; + icontext.nocreate4 = otyp; } if (urace.malenum != PM_HUMAN) {