From 9441bafb091fbc510e48e3360770c8b63782de2d Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 5 Sep 2021 14:38:51 -0500 Subject: [PATCH 1/4] Restructure the code to be able to possibly support loadfile. --- src/blua/lbaselib.c | 2 +- src/lua_script.c | 88 +++++++++++++++++++++++++++++++++++---------- src/lua_script.h | 3 +- src/w_wad.c | 8 ++--- 4 files changed, 76 insertions(+), 25 deletions(-) diff --git a/src/blua/lbaselib.c b/src/blua/lbaselib.c index 644565c28..9d4e30eb1 100644 --- a/src/blua/lbaselib.c +++ b/src/blua/lbaselib.c @@ -282,7 +282,7 @@ static int luaB_dofile (lua_State *L) { if (lumpnum == INT16_MAX) luaL_error(L, "can't find script " LUA_QS, fullfilename); - LUA_LoadLump(numwadfiles - 1, lumpnum, false); + LUA_DoLump(numwadfiles - 1, lumpnum, false); return lua_gettop(L) - n; } diff --git a/src/lua_script.c b/src/lua_script.c index 9eb1912b3..1cc95306e 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -554,64 +554,114 @@ void LUA_ClearExtVars(void) INT32 lua_lumploading = 0; // Load a script from a MYFILE -static inline void LUA_LoadFile(MYFILE *f, char *name, boolean noresults) +static inline boolean LUA_LoadFile(MYFILE *f, char *name) { int errorhandlerindex; + boolean success; if (!name) name = wadfiles[f->wad]->filename; + CONS_Printf("Loading Lua script from %s\n", name); + if (!gL) // Lua needs to be initialized LUA_ClearState(); + lua_pushinteger(gL, f->wad); lua_setfield(gL, LUA_REGISTRYINDEX, "WAD"); + lua_pushcfunction(gL, LUA_GetErrorMessage); + errorhandlerindex = lua_gettop(gL); + + success = !luaL_loadbuffer(gL, f->data, f->size, va("@%s",name)); + + if (!success) { + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); + lua_pop(gL,1); + } + + lua_gc(gL, LUA_GCCOLLECT, 0); + lua_remove(gL, errorhandlerindex); + + return success; +} + +// Runs a script loaded by LUA_LoadFile. +static inline void LUA_DoFile(boolean noresults) +{ + int errorhandlerindex; + + if (!gL) // LUA_LoadFile should've allocated gL for us! + return; + lua_lumploading++; // turn on loading flag lua_pushcfunction(gL, LUA_GetErrorMessage); - errorhandlerindex = lua_gettop(gL); - if (luaL_loadbuffer(gL, f->data, f->size, va("@%s",name)) || lua_pcall(gL, 0, noresults ? 0 : LUA_MULTRET, lua_gettop(gL) - 1)) { + lua_insert(gL, -2); // move the function we're calling to the top. + errorhandlerindex = lua_gettop(gL) - 1; + + if (lua_pcall(gL, 0, noresults ? 0 : LUA_MULTRET, lua_gettop(gL) - 1)) { CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); lua_pop(gL,1); } + lua_gc(gL, LUA_GCCOLLECT, 0); lua_remove(gL, errorhandlerindex); lua_lumploading--; // turn off again } -// Load a script from a lump -void LUA_LoadLump(UINT16 wad, UINT16 lump, boolean noresults) +static inline MYFILE *LUA_GetFile(UINT16 wad, UINT16 lump, char **name) { - MYFILE f; - char *name; + MYFILE *f = Z_Malloc(sizeof(MYFILE), PU_LUA, NULL); size_t len; - f.wad = wad; - f.size = W_LumpLengthPwad(wad, lump); - f.data = Z_Malloc(f.size, PU_LUA, NULL); - W_ReadLumpPwad(wad, lump, f.data); - f.curpos = f.data; + + f->wad = wad; + f->size = W_LumpLengthPwad(wad, lump); + f->data = Z_Malloc(f->size, PU_LUA, NULL); + W_ReadLumpPwad(wad, lump, f->data); + f->curpos = f->data; len = strlen(wadfiles[wad]->filename); // length of file name if (wadfiles[wad]->type == RET_LUA) { - name = malloc(len+1); - strcpy(name, wadfiles[wad]->filename); + *name = malloc(len+1); + strcpy(*name, wadfiles[wad]->filename); } else // If it's not a .lua file, copy the lump name in too. { lumpinfo_t *lump_p = &wadfiles[wad]->lumpinfo[lump]; len += 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name - name = malloc(len+1); - sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->fullname); - name[len] = '\0'; + *name = malloc(len+1); + sprintf(*name, "%s|%s", wadfiles[wad]->filename, lump_p->fullname); + (*name)[len] = '\0'; // annoying that index takes priority over dereference, but w/e } - LUA_LoadFile(&f, name, noresults); // actually load file! + return f; +} + +// Load a script from a lump +boolean LUA_LoadLump(UINT16 wad, UINT16 lump) +{ + char *name = NULL; + MYFILE *f = LUA_GetFile(wad, lump, &name); + boolean success = LUA_LoadFile(f, name); // actually load file! free(name); - Z_Free(f.data); + + Z_Free(f->data); + Z_Free(f); + + return success; +} + +void LUA_DoLump(UINT16 wad, UINT16 lump, boolean noresults) +{ + boolean success = LUA_LoadLump(wad, lump); + + if (success) + LUA_DoFile(noresults); // run it } #ifdef LUA_ALLOW_BYTECODE diff --git a/src/lua_script.h b/src/lua_script.h index e88256941..6b7c21124 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -45,7 +45,8 @@ extern INT32 lua_lumploading; // is LUA_LoadLump being called? int LUA_GetErrorMessage(lua_State *L); int LUA_Call(lua_State *L, int nargs, int nresults, int errorhandlerindex); -void LUA_LoadLump(UINT16 wad, UINT16 lump, boolean noresults); +boolean LUA_LoadLump(UINT16 wad, UINT16 lump); +void LUA_DoLump(UINT16 wad, UINT16 lump, boolean noresults); #ifdef LUA_ALLOW_BYTECODE void LUA_DumpFile(const char *filename); #endif diff --git a/src/w_wad.c b/src/w_wad.c index cbff5c67b..e3dc3a971 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -199,7 +199,7 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile) posStart = W_CheckNumForFullNamePK3("Init.lua", wadnum, 0); if (posStart != INT16_MAX) { - LUA_LoadLump(wadnum, posStart, true); + LUA_DoLump(wadnum, posStart, true); } else { @@ -208,7 +208,7 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile) { posEnd = W_CheckNumForFolderEndPK3("Lua/", wadnum, posStart); for (; posStart < posEnd; posStart++) - LUA_LoadLump(wadnum, posStart, true); + LUA_DoLump(wadnum, posStart, true); } } @@ -241,7 +241,7 @@ static inline void W_LoadDehackedLumps(UINT16 wadnum, boolean mainfile) lumpinfo_t *lump_p = wadfiles[wadnum]->lumpinfo; for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++) if (memcmp(lump_p->name,"LUA_",4)==0) - LUA_LoadLump(wadnum, lump, true); + LUA_DoLump(wadnum, lump, true); } { @@ -879,7 +879,7 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) DEH_LoadDehackedLumpPwad(numwadfiles - 1, 0, mainfile); break; case RET_LUA: - LUA_LoadLump(numwadfiles - 1, 0, true); + LUA_DoLump(numwadfiles - 1, 0, true); break; default: break; From bd9118eae7b9f4c988b2d6e072c150d8a84db720 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 5 Sep 2021 14:52:40 -0500 Subject: [PATCH 2/4] Implement loadfile --- src/blua/lbaselib.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/blua/lbaselib.c b/src/blua/lbaselib.c index 9d4e30eb1..830043f30 100644 --- a/src/blua/lbaselib.c +++ b/src/blua/lbaselib.c @@ -287,6 +287,25 @@ static int luaB_dofile (lua_State *L) { return lua_gettop(L) - n; } +// Edited to load PK3 entries instead +static int luaB_loadfile (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + char fullfilename[256]; + UINT16 lumpnum; + int n = lua_gettop(L); + + if (wadfiles[numwadfiles - 1]->type != RET_PK3) + luaL_error(L, "loadfile() only works with PK3 files"); + + snprintf(fullfilename, sizeof(fullfilename), "Lua/%s", filename); + lumpnum = W_CheckNumForFullNamePK3(fullfilename, numwadfiles - 1, 0); + if (lumpnum == INT16_MAX) + luaL_error(L, "can't find script " LUA_QS, fullfilename); + + LUA_LoadLump(numwadfiles - 1, lumpnum); + + return 1; +} static int luaB_assert (lua_State *L) { luaL_checkany(L, 1); @@ -406,6 +425,7 @@ static const luaL_Reg base_funcs[] = { {"collectgarbage", luaB_collectgarbage}, {"error", luaB_error}, {"dofile", luaB_dofile}, + {"loadfile", luaB_loadfile}, {"gcinfo", luaB_gcinfo}, {"getfenv", luaB_getfenv}, {"getmetatable", luaB_getmetatable}, From 6f19615fabe216537d4d59b5a0de717c7df755b1 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Mon, 6 Sep 2021 15:05:34 -0500 Subject: [PATCH 3/4] Remove unused variable to fix warning in luaB_loadfile. --- src/blua/lbaselib.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/blua/lbaselib.c b/src/blua/lbaselib.c index 830043f30..d7bdc8204 100644 --- a/src/blua/lbaselib.c +++ b/src/blua/lbaselib.c @@ -292,7 +292,6 @@ static int luaB_loadfile (lua_State *L) { const char *filename = luaL_checkstring(L, 1); char fullfilename[256]; UINT16 lumpnum; - int n = lua_gettop(L); if (wadfiles[numwadfiles - 1]->type != RET_PK3) luaL_error(L, "loadfile() only works with PK3 files"); From b3ef2b3344e0f510f4f24dd6f3c21326ca2e5eda Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 28 Dec 2023 17:32:36 +0100 Subject: [PATCH 4/4] Support loadfile in folder add-ons too --- src/blua/lbaselib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/blua/lbaselib.c b/src/blua/lbaselib.c index 452f101c4..2bb3d9cf0 100644 --- a/src/blua/lbaselib.c +++ b/src/blua/lbaselib.c @@ -275,7 +275,7 @@ static int luaB_dofile (lua_State *L) { int n = lua_gettop(L); if (!W_FileHasFolders(wadfiles[numwadfiles - 1])) - luaL_error(L, "dofile() only works with PK3 files"); + luaL_error(L, "dofile() only works with PK3 files and folders"); snprintf(fullfilename, sizeof(fullfilename), "Lua/%s", filename); lumpnum = W_CheckNumForFullNamePK3(fullfilename, numwadfiles - 1, 0); @@ -293,8 +293,8 @@ static int luaB_loadfile (lua_State *L) { char fullfilename[256]; UINT16 lumpnum; - if (wadfiles[numwadfiles - 1]->type != RET_PK3) - luaL_error(L, "loadfile() only works with PK3 files"); + if (!W_FileHasFolders(wadfiles[numwadfiles - 1])) + luaL_error(L, "loadfile() only works with PK3 files and folders"); snprintf(fullfilename, sizeof(fullfilename), "Lua/%s", filename); lumpnum = W_CheckNumForFullNamePK3(fullfilename, numwadfiles - 1, 0);