]> granicus.if.org Git - nethack/commitdiff
Initial check-in of icontext work.
authorBart House <bart@barthouse.com>
Thu, 22 Nov 2018 21:01:58 +0000 (13:01 -0800)
committerBart House <bart@barthouse.com>
Fri, 23 Nov 2018 04:53:24 +0000 (20:53 -0800)
include/config.h
include/decl.h
include/extern.h
src/decl.c
src/dog.c
src/pickup.c
sys/share/pcmain.c
sys/winnt/stubs.c
util/lev_main.c
win/share/tile2bmp.c
win/win32/winhack.c

index 4f242679aa7fb14bd28e586dcacd4fbdf74137ee..d4f67e1ac150b2fa65085de4e5fa4a9647586cab 100644 (file)
@@ -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 */
 
index 992e86ad58cca80de823f12899895dfd52a2438d..2cc7f965cc0d121540707f366c96f9543dc08778 100644 (file)
@@ -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 */
index 89910b0bba91889ff9ffa71c67dbdce7456ff5f3..d3a251b83666e332cb009b4da3c3e2c1b8d8633d 100644 (file)
@@ -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 ### */
 
index ffd9ef97414dde2b972b20cae6856efc4bac9448..edfeb3a60441c2d5aa449b029926005306487b99 100644 (file)
@@ -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*/
index 0d967195eacf31739e6a694342b18077f46c0dfc..7c1b62e8b205c94afe079a8fcfe157312e35f11c 100644 (file)
--- 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);
index d68def38d7026a56e3e08f30954f060a2605b285..83d5eb2735abc742a63d0ad037d288526fc559ec 100644 (file)
@@ -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;
 }
 
index 93674ab341dd2e7c191d0a6fb607bd061db87390..932ec971e5aa7b48cb35e4452f904cbcebaebaf9 100644 (file)
@@ -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
index bb5ad82e432b246ea94bcf80a412f29f571af084..9e16c6dce274cfdf2d67d248584ad83d379c3e3f 100644 (file)
@@ -37,6 +37,7 @@ char *argv[];
 {
     boolean resuming;
 
+    icontext_init();
     sys_early_init();
     Strcpy(default_window_sys, "tty");
     resuming = pcmain(argc, argv);
index ecf7a444c45ef9b120b70bfcc33025c78e905963..72954979151e2777ca606148627b1b765b7c0314 100644 (file)
@@ -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*/
index ca2c7dd734a2cd1180661450dee2d6c9d29ca263..6722bbc26a75ba3bb0db5c1a7d1719a24d8187c9 100644 (file)
@@ -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);
+}
index 9dcbb4e4b066078d681f5d22e55551e579cadd4c..ef48d6b639a4df1e96957e7b9786a316b1d48ed8 100644 (file)
@@ -97,6 +97,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
 
     win10_init();
 
+    icontext_init();
     sys_early_init();
 
     /* init applicatio structure */