diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 05ed99bd2..7f7371c8a 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.25 $ $NHDT-Date: 1559035655 2019/05/28 09:27:35 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.26 $ $NHDT-Date: 1559088523 2019/05/29 00:08:43 $ This fixes36.3 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.2 in May 2019. Please note, however, @@ -30,6 +30,8 @@ free ball and chain if Punished hero dies while descending stairs or dies or quits while swallowed; put ball and chain in bones for the stairs case if hero dies while a thrown or kicked object is in transit, put that object on the map in case bones data gets saved +fix a memory leak that occurred if player used wizard mode to leave and return + to the Plane of Air or Plane of Water (not possible in normal play) Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/src/do.c b/src/do.c index 629028c1d..6d6953f9d 100644 --- a/src/do.c +++ b/src/do.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do.c $NHDT-Date: 1548978604 2019/01/31 23:50:04 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.189 $ */ +/* NetHack 3.6 do.c $NHDT-Date: 1559088523 2019/05/29 00:08:43 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.190 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1358,6 +1358,16 @@ boolean at_stairs, falling, portal; } savelev(fd, ledger_no(&u.uz), cant_go_back ? FREE_SAVE : (WRITE_SAVE | FREE_SAVE)); + /* air bubbles and clouds are saved in game-state rather than with the + level they're used on; in normal play, you can't leave and return + to any endgame level--bubbles aren't needed once you move to the + next level so used to be discarded when the next special level was + loaded; but in wizard mode you can leave and return, and since they + aren't saved with the level and restored upon return (new ones are + created instead), we need to discard them to avoid a memory leak; + so bubbles are now discarded as we leave the level they're used on */ + if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) + save_waterlevel(fd, FREE_SAVE); /* note: doesn't use 'fd' */ bclose(fd); if (cant_go_back) { /* discard unreachable levels; keep #0 */ @@ -1421,6 +1431,7 @@ boolean at_stairs, falling, portal; oinit(); /* reassign level dependent obj probabilities */ } reglyph_darkroom(); + u.uinwater = 0; /* do this prior to level-change pline messages */ vision_reset(); /* clear old level's line-of-sight */ g.vision_full_recalc = 0; /* don't let that reenable vision yet */ diff --git a/src/mkmaze.c b/src/mkmaze.c index f835d5ca1..afcff0027 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkmaze.c $NHDT-Date: 1558562368 2019/05/22 21:59:28 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.70 $ */ +/* NetHack 3.6 mkmaze.c $NHDT-Date: 1559088524 2019/05/29 00:08:44 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.71 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -464,14 +464,8 @@ fixup_special() struct mkroom *croom; boolean added_branch = FALSE; - if (g.was_waterlevel) { - g.was_waterlevel = FALSE; - u.uinwater = 0; - unsetup_waterlevel(); - } if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) { g.level.flags.hero_memory = 0; - g.was_waterlevel = TRUE; /* water level is an odd beast - it has to be set up before calling place_lregions etc. */ setup_waterlevel(); @@ -489,6 +483,7 @@ fixup_special() lev.dlevel = atoi(r->rname.str); } else { s_level *sp = find_level(r->rname.str); + lev = sp->dlevel; } /*FALLTHRU*/ @@ -1562,13 +1557,13 @@ int fd, mode; int n = 0; for (b = g.bbubbles; b; b = b->next) ++n; - bwrite(fd, (genericptr_t) &n, sizeof(int)); - bwrite(fd, (genericptr_t) &g.xmin, sizeof(int)); - bwrite(fd, (genericptr_t) &g.ymin, sizeof(int)); - bwrite(fd, (genericptr_t) &g.xmax, sizeof(int)); - bwrite(fd, (genericptr_t) &g.ymax, sizeof(int)); + bwrite(fd, (genericptr_t) &n, sizeof n); + bwrite(fd, (genericptr_t) &g.xmin, sizeof g.xmin); + bwrite(fd, (genericptr_t) &g.ymin, sizeof g.ymin); + bwrite(fd, (genericptr_t) &g.xmax, sizeof g.xmax); + bwrite(fd, (genericptr_t) &g.ymax, sizeof g.ymax); for (b = g.bbubbles; b; b = b->next) - bwrite(fd, (genericptr_t) b, sizeof(struct bubble)); + bwrite(fd, (genericptr_t) b, sizeof *b); } if (release_data(mode)) unsetup_waterlevel(); @@ -1585,15 +1580,15 @@ int fd; return; set_wportal(); - mread(fd, (genericptr_t) &n, sizeof(int)); - mread(fd, (genericptr_t) &g.xmin, sizeof(int)); - mread(fd, (genericptr_t) &g.ymin, sizeof(int)); - mread(fd, (genericptr_t) &g.xmax, sizeof(int)); - mread(fd, (genericptr_t) &g.ymax, sizeof(int)); + mread(fd, (genericptr_t) &n, sizeof n); + mread(fd, (genericptr_t) &g.xmin, sizeof g.xmin); + mread(fd, (genericptr_t) &g.ymin, sizeof g.ymin); + mread(fd, (genericptr_t) &g.xmax, sizeof g.xmax); + mread(fd, (genericptr_t) &g.ymax, sizeof g.ymax); for (i = 0; i < n; i++) { btmp = b; - b = (struct bubble *) alloc(sizeof(struct bubble)); - mread(fd, (genericptr_t) b, sizeof(struct bubble)); + b = (struct bubble *) alloc(sizeof *b); + mread(fd, (genericptr_t) b, sizeof *b); if (g.bbubbles) { btmp->next = b; b->prev = btmp; @@ -1605,7 +1600,6 @@ int fd; } g.ebubbles = b; b->next = (struct bubble *) 0; - g.was_waterlevel = TRUE; } const char * @@ -1728,7 +1722,7 @@ int x, y, n; if (bmask[n][1] > MAX_BMASK) { panic("bmask size is larger than MAX_BMASK"); } - b = (struct bubble *) alloc(sizeof(struct bubble)); + b = (struct bubble *) alloc(sizeof *b); if ((x + (int) bmask[n][0] - 1) > gbxmax) x = gbxmax - bmask[n][0] + 1; if ((y + (int) bmask[n][1] - 1) > gbymax) @@ -1739,7 +1733,7 @@ int x, y, n; b->dy = 1 - rn2(3); /* y dimension is the length of bitmap data - see bmask above */ (void) memcpy((genericptr_t) b->bm, (genericptr_t) bmask[n], - (bmask[n][1] + 2) * sizeof(b->bm[0])); + (bmask[n][1] + 2) * sizeof (b->bm[0])); b->cons = 0; if (!g.bbubbles) g.bbubbles = b; diff --git a/sys/winnt/winnt.c b/sys/winnt/winnt.c index d583253b5..f6a9aa791 100644 --- a/sys/winnt/winnt.c +++ b/sys/winnt/winnt.c @@ -54,6 +54,7 @@ static HWND GetConsoleHwnd(void); extern void NDECL(backsp); #endif int NDECL(windows_console_custom_nhgetch); +extern void NDECL(safe_routines); /* The function pointer nt_kbhit contains a kbhit() equivalent * which varies depending on which window port is active. @@ -251,35 +252,18 @@ Delay(int ms) void win32_abort() { - boolean is_tty = FALSE; + int c; -#ifdef TTY_GRAPHICS - is_tty = WINDOWPORT("tty"); -#endif + if (WINDOWPORT("mswin") || WINDOWPORT("tty")) { + if (iflags.window_inited) + exit_nhwindows((char *) 0); + iflags.window_inited = FALSE; + } + if (!WINDOWPORT("mswin") && !WINDOWPORT("safe-startup")) + safe_routines(); if (wizard) { - int c, ci, ct; - - if (!iflags.window_inited) - c = 'n'; - ct = 0; - msmsg("Execute debug breakpoint wizard?"); - while ((ci = nhgetch()) != '\n') { - if (ct > 0) { - if (is_tty) - backsp(); /* \b is visible on NT console */ - (void) putchar(' '); - if (is_tty) - backsp(); - ct = 0; - c = 'n'; - } - if (ci == 'y' || ci == 'n' || ci == 'Y' || ci == 'N') { - ct = 1; - c = ci; - msmsg("%c", c); - } - } - if (c == 'y') + raw_print("Execute debug breakpoint wizard?"); + if ((c = nhgetch()) == 'y' || c == 'Y') DebugBreak(); } abort(); @@ -540,13 +524,16 @@ void getreturn(str) const char *str; { + static boolean in_getreturn = FALSE; char buf[BUFSZ]; - if (!getreturn_enabled) + if (in_getreturn || !getreturn_enabled) return; + in_getreturn = TRUE; Sprintf(buf,"Hit %s.", str); raw_print(buf); wait_synch(); + in_getreturn = FALSE; return; }