From: PatR Date: Wed, 6 May 2020 01:06:00 +0000 (-0700) Subject: move lua context out of dungeons[] X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a51e44e532d28457ca227c85e1ec45024503a9a7;p=nethack move lua context out of dungeons[] and out of save files so restore doesn't need to clear stale data. Behavior should be the same as before, except that when entering the endgame branch and discarding the main dungeon and its other branches, lua theme context is now discarded for those too. --- diff --git a/include/decl.h b/include/decl.h index 6b7142e57..1caf4c5bc 100644 --- a/include/decl.h +++ b/include/decl.h @@ -949,6 +949,7 @@ struct instance_globals { int mhitu_dieroll; /* mklev.c */ + genericptr_t luathemes[MAXDUNGEON]; xchar vault_x; xchar vault_y; boolean made_branch; /* used only during level creation */ diff --git a/include/dungeon.h b/include/dungeon.h index eba96d8bd..b0e3c1b93 100644 --- a/include/dungeon.h +++ b/include/dungeon.h @@ -67,7 +67,6 @@ typedef struct dungeon { /* basic dungeon identifier */ xchar dunlev_ureached; /* how deep you have been in this dungeon */ int ledger_start, /* the starting depth in "real" terms */ depth_start; /* the starting depth in "logical" terms */ - lua_State *themelua; /* themerms compiled lua */ } dungeon; /* diff --git a/include/extern.h b/include/extern.h index a5730affc..6d177cb8c 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1325,6 +1325,7 @@ E void NDECL(sort_rooms); E void FDECL(add_room, (int, int, int, int, BOOLEAN_P, SCHAR_P, BOOLEAN_P)); E void FDECL(add_subroom, (struct mkroom *, int, int, int, int, BOOLEAN_P, SCHAR_P, BOOLEAN_P)); +E void FDECL(free_luathemes, (BOOLEAN_P)); E void NDECL(makecorridors); E void FDECL(add_door, (int, int, struct mkroom *)); E void NDECL(clear_level_structures); diff --git a/include/patchlevel.h b/include/patchlevel.h index b02d2d613..24b92cf36 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -14,7 +14,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 19 +#define EDITLEVEL 20 #define COPYRIGHT_BANNER_A "NetHack, Copyright 1985-2020" #define COPYRIGHT_BANNER_B \ diff --git a/src/decl.c b/src/decl.c index a6de86e35..0f078496b 100644 --- a/src/decl.c +++ b/src/decl.c @@ -413,7 +413,7 @@ const struct instance_globals g_init = { DUMMY, /* warnsyms */ /* dungeon.c */ - UNDEFINED_VALUE, /* n_dgns */ + 0, /* n_dgns */ NULL, /* branches */ NULL, /* mapseenchn */ @@ -478,6 +478,7 @@ const struct instance_globals g_init = { UNDEFINED_VALUE, /* mhitu_dieroll */ /* mklev.c */ + UNDEFINED_VALUES, /* luathemes[] */ UNDEFINED_VALUE, /* vault_x */ UNDEFINED_VALUE, /* vault_y */ UNDEFINED_VALUE, /* made_branch */ diff --git a/src/do.c b/src/do.c index 530f09a61..8feb069a5 100644 --- a/src/do.c +++ b/src/do.c @@ -1420,6 +1420,8 @@ boolean at_stairs, falling, portal; update_mlstmv(); /* current monsters are becoming inactive */ if (nhfp->structlevel) bufon(nhfp->fd); /* use buffered output */ + } else { + free_luathemes(TRUE); } save_mode = nhfp->mode; nhfp->mode = cant_go_back ? FREEING : (WRITING | FREEING); diff --git a/src/dungeon.c b/src/dungeon.c index e5c2be68b..f376e5237 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -144,23 +144,24 @@ boolean perform_write, free_data; bwrite(nhfp->fd, (genericptr_t) &g.n_dgns, sizeof g.n_dgns); bwrite(nhfp->fd, (genericptr_t) g.dungeons, sizeof(dungeon) * (unsigned) g.n_dgns); - bwrite(nhfp->fd, (genericptr_t) &g.dungeon_topology, sizeof g.dungeon_topology); + bwrite(nhfp->fd, (genericptr_t) &g.dungeon_topology, + sizeof g.dungeon_topology); bwrite(nhfp->fd, (genericptr_t) g.tune, sizeof tune); } for (count = 0, curr = g.branches; curr; curr = curr->next) count++; if (nhfp->structlevel) - bwrite(nhfp->fd, (genericptr_t) &count, sizeof(count)); + bwrite(nhfp->fd, (genericptr_t) &count, sizeof count); for (curr = g.branches; curr; curr = curr->next) { if (nhfp->structlevel) - bwrite(nhfp->fd, (genericptr_t) curr, sizeof(branch)); + bwrite(nhfp->fd, (genericptr_t) curr, sizeof *curr); } count = maxledgerno(); if (nhfp->structlevel) { bwrite(nhfp->fd, (genericptr_t) &count, sizeof count); bwrite(nhfp->fd, (genericptr_t) g.level_info, - (unsigned) count * sizeof(struct linfo)); + (unsigned) count * sizeof (struct linfo)); bwrite(nhfp->fd, (genericptr_t) &g.inv_pos, sizeof g.inv_pos); } for (count = 0, curr_ms = g.mapseenchn; curr_ms; @@ -168,7 +169,7 @@ boolean perform_write, free_data; count++; if (nhfp->structlevel) - bwrite(nhfp->fd, (genericptr_t) &count, sizeof(count)); + bwrite(nhfp->fd, (genericptr_t) &count, sizeof count); for (curr_ms = g.mapseenchn; curr_ms; curr_ms = curr_ms->next) { save_mapseen(nhfp, curr_ms); @@ -203,23 +204,22 @@ NHFILE *nhfp; mapseen *curr_ms, *last_ms; if (nhfp->structlevel) { - mread(nhfp->fd, (genericptr_t) &g.n_dgns, sizeof(g.n_dgns)); - mread(nhfp->fd, (genericptr_t) g.dungeons, sizeof(dungeon) * (unsigned) g.n_dgns); - mread(nhfp->fd, (genericptr_t) &g.dungeon_topology, sizeof g.dungeon_topology); + mread(nhfp->fd, (genericptr_t) &g.n_dgns, sizeof g.n_dgns); + mread(nhfp->fd, (genericptr_t) g.dungeons, + sizeof (dungeon) * (unsigned) g.n_dgns); + mread(nhfp->fd, (genericptr_t) &g.dungeon_topology, + sizeof g.dungeon_topology); mread(nhfp->fd, (genericptr_t) g.tune, sizeof tune); } last = g.branches = (branch *) 0; - for (i = 0; i < g.n_dgns; i++) - g.dungeons[i].themelua = (lua_State *) 0; - if (nhfp->structlevel) - mread(nhfp->fd, (genericptr_t) &count, sizeof(count)); + mread(nhfp->fd, (genericptr_t) &count, sizeof count); for (i = 0; i < count; i++) { - curr = (branch *) alloc(sizeof(branch)); + curr = (branch *) alloc(sizeof *curr); if (nhfp->structlevel) - mread(nhfp->fd, (genericptr_t) curr, sizeof(branch)); + mread(nhfp->fd, (genericptr_t) curr, sizeof *curr); curr->next = (branch *) 0; if (last) last->next = curr; @@ -229,18 +229,18 @@ NHFILE *nhfp; } if (nhfp->structlevel) - mread(nhfp->fd, (genericptr_t) &count, sizeof(count)); + mread(nhfp->fd, (genericptr_t) &count, sizeof count); if (count >= MAXLINFO) panic("level information count larger (%d) than allocated size", count); if (nhfp->structlevel) mread(nhfp->fd, (genericptr_t) g.level_info, - (unsigned) count * sizeof(struct linfo)); + (unsigned) count * sizeof (struct linfo)); if (nhfp->structlevel) { mread(nhfp->fd, (genericptr_t) &g.inv_pos, sizeof g.inv_pos); - mread(nhfp->fd, (genericptr_t) &count, sizeof(count)); + mread(nhfp->fd, (genericptr_t) &count, sizeof count); } last_ms = (mapseen *) 0; @@ -1030,7 +1030,6 @@ init_dungeons() Strcpy(g.dungeons[i].dname, dgn_name); /* FIXME: dname length */ Strcpy(g.dungeons[i].proto, dgn_protoname); /* FIXME: proto length */ Strcpy(g.dungeons[i].themerms, dgn_themerms); /* FIXME: length */ - g.dungeons[i].themelua = (lua_State *) 0; g.dungeons[i].boneid = *dgn_bonetag ? *dgn_bonetag : 0; free((genericptr) dgn_fill); /* free((genericptr) dgn_protoname); -- stored in pd.tmpdungeon[] */ diff --git a/src/mklev.c b/src/mklev.c index 71f6f4bef..007262ea0 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -239,30 +239,46 @@ boolean special; g.nsubroom++; } +void +free_luathemes(keependgame) +boolean keependgame; /* False: exiting, True: discarding main dungeon */ +{ + int i; + + for (i = 0; i < g.n_dgns; ++i) { + if (keependgame && i == astral_level.dnum) + continue; + if (g.luathemes[i]) { + lua_close((lua_State *) g.luathemes[i]); + g.luathemes[i] = (lua_State *) 0; + } + } +} + static void makerooms() { boolean tried_vault = FALSE; int themeroom_tries = 0; - boolean dothemes = (g.dungeons[u.uz.dnum].themelua != NULL); - char *fname = g.dungeons[u.uz.dnum].themerms; + char *fname; + lua_State *themes = (lua_State *) g.luathemes[u.uz.dnum]; - if (*fname && !g.dungeons[u.uz.dnum].themelua) { - g.dungeons[u.uz.dnum].themelua = nhl_init(); - if (g.dungeons[u.uz.dnum].themelua) { - if (!nhl_loadlua(g.dungeons[u.uz.dnum].themelua, fname)) { + if (!themes && *(fname = g.dungeons[u.uz.dnum].themerms)) { + if ((themes = nhl_init()) != 0) { + if (!nhl_loadlua(themes, fname)) { /* loading lua failed, don't use themed rooms */ - g.dungeons[u.uz.dnum].themerms[0] = '\0'; - lua_close(g.dungeons[u.uz.dnum].themelua); - g.dungeons[u.uz.dnum].themelua = NULL; - dothemes = FALSE; + lua_close(themes); + themes = (lua_State *) 0; } else { - dothemes = TRUE; + /* success; save state for this dungeon branch */ + g.luathemes[u.uz.dnum] = (genericptr_t) themes; } } + if (!themes) /* don't try again when making next level */ + *fname = '\0'; /* g.dungeons[u.uz.dnum].themerms */ } - if (dothemes) { + if (themes) { create_des_coder(); } @@ -277,12 +293,11 @@ makerooms() g.rooms[g.nroom].hx = -1; } } else { - if (dothemes) { + if (themes) { g.in_mk_themerooms = TRUE; g.themeroom_failed = FALSE; - lua_getglobal(g.dungeons[u.uz.dnum].themelua, - "themerooms_generate"); - lua_call(g.dungeons[u.uz.dnum].themelua, 0, 0); + lua_getglobal(themes, "themerooms_generate"); + lua_call(themes, 0, 0); g.in_mk_themerooms = FALSE; if (g.themeroom_failed && ((themeroom_tries++ > 10) @@ -294,7 +309,7 @@ makerooms() } } } - if (dothemes) { + if (themes) { wallification(1, 0, COLNO - 1, ROWNO - 1); free(g.coder); g.coder = NULL; diff --git a/src/save.c b/src/save.c index c2d710f4c..b3fe86656 100644 --- a/src/save.c +++ b/src/save.c @@ -1070,17 +1070,12 @@ free_dungeons() { #ifdef FREE_ALL_MEMORY NHFILE tnhfp; - int i; zero_nhfile(&tnhfp); /* also sets fd to -1 */ tnhfp.mode = FREEING; savelevchn(&tnhfp); save_dungeon(&tnhfp, FALSE, TRUE); - for (i = 0; i < g.n_dgns; i++) - if (g.dungeons[i].themelua) { - lua_close(g.dungeons[i].themelua); - g.dungeons[i].themelua = (lua_State *) 0; - } + free_luathemes(TRUE); #endif return; }