Merge branch 'loadfile' into 'next'

`loadfile` in Lua

See merge request STJr/SRB2!1615
This commit is contained in:
LJ Sonic 2023-12-28 17:08:10 +00:00
commit c2a8d1f7ea
4 changed files with 96 additions and 26 deletions

View file

@ -275,18 +275,36 @@ static int luaB_dofile (lua_State *L) {
int n = lua_gettop(L); int n = lua_gettop(L);
if (!W_FileHasFolders(wadfiles[numwadfiles - 1])) 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); snprintf(fullfilename, sizeof(fullfilename), "Lua/%s", filename);
lumpnum = W_CheckNumForFullNamePK3(fullfilename, numwadfiles - 1, 0); lumpnum = W_CheckNumForFullNamePK3(fullfilename, numwadfiles - 1, 0);
if (lumpnum == INT16_MAX) if (lumpnum == INT16_MAX)
luaL_error(L, "can't find script " LUA_QS, fullfilename); 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; 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;
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);
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) { static int luaB_assert (lua_State *L) {
luaL_checkany(L, 1); luaL_checkany(L, 1);
@ -406,6 +424,7 @@ static const luaL_Reg base_funcs[] = {
{"collectgarbage", luaB_collectgarbage}, {"collectgarbage", luaB_collectgarbage},
{"error", luaB_error}, {"error", luaB_error},
{"dofile", luaB_dofile}, {"dofile", luaB_dofile},
{"loadfile", luaB_loadfile},
{"gcinfo", luaB_gcinfo}, {"gcinfo", luaB_gcinfo},
{"getfenv", luaB_getfenv}, {"getfenv", luaB_getfenv},
{"getmetatable", luaB_getmetatable}, {"getmetatable", luaB_getmetatable},

View file

@ -604,64 +604,114 @@ void LUA_ClearExtVars(void)
INT32 lua_lumploading = 0; INT32 lua_lumploading = 0;
// Load a script from a MYFILE // 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; int errorhandlerindex;
boolean success;
if (!name) if (!name)
name = wadfiles[f->wad]->filename; name = wadfiles[f->wad]->filename;
CONS_Printf("Loading Lua script from %s\n", name); CONS_Printf("Loading Lua script from %s\n", name);
if (!gL) // Lua needs to be initialized if (!gL) // Lua needs to be initialized
LUA_ClearState(); LUA_ClearState();
lua_pushinteger(gL, f->wad); lua_pushinteger(gL, f->wad);
lua_setfield(gL, LUA_REGISTRYINDEX, "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_lumploading++; // turn on loading flag
lua_pushcfunction(gL, LUA_GetErrorMessage); lua_pushcfunction(gL, LUA_GetErrorMessage);
errorhandlerindex = lua_gettop(gL); lua_insert(gL, -2); // move the function we're calling to the top.
if (luaL_loadbuffer(gL, f->data, f->size, va("@%s",name)) || lua_pcall(gL, 0, noresults ? 0 : LUA_MULTRET, lua_gettop(gL) - 1)) { 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)); CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
lua_pop(gL,1); lua_pop(gL,1);
} }
lua_gc(gL, LUA_GCCOLLECT, 0); lua_gc(gL, LUA_GCCOLLECT, 0);
lua_remove(gL, errorhandlerindex); lua_remove(gL, errorhandlerindex);
lua_lumploading--; // turn off again lua_lumploading--; // turn off again
} }
// Load a script from a lump static inline MYFILE *LUA_GetFile(UINT16 wad, UINT16 lump, char **name)
void LUA_LoadLump(UINT16 wad, UINT16 lump, boolean noresults)
{ {
MYFILE f; MYFILE *f = Z_Malloc(sizeof(MYFILE), PU_LUA, NULL);
char *name;
size_t len; size_t len;
f.wad = wad;
f.size = W_LumpLengthPwad(wad, lump); f->wad = wad;
f.data = Z_Malloc(f.size, PU_LUA, NULL); f->size = W_LumpLengthPwad(wad, lump);
W_ReadLumpPwad(wad, lump, f.data); f->data = Z_Malloc(f->size, PU_LUA, NULL);
f.curpos = f.data; W_ReadLumpPwad(wad, lump, f->data);
f->curpos = f->data;
len = strlen(wadfiles[wad]->filename); // length of file name len = strlen(wadfiles[wad]->filename); // length of file name
if (wadfiles[wad]->type == RET_LUA) if (wadfiles[wad]->type == RET_LUA)
{ {
name = malloc(len+1); *name = malloc(len+1);
strcpy(name, wadfiles[wad]->filename); strcpy(*name, wadfiles[wad]->filename);
} }
else // If it's not a .lua file, copy the lump name in too. else // If it's not a .lua file, copy the lump name in too.
{ {
lumpinfo_t *lump_p = &wadfiles[wad]->lumpinfo[lump]; lumpinfo_t *lump_p = &wadfiles[wad]->lumpinfo[lump];
len += 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name len += 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name
name = malloc(len+1); *name = malloc(len+1);
sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->fullname); sprintf(*name, "%s|%s", wadfiles[wad]->filename, lump_p->fullname);
name[len] = '\0'; (*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); 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 #ifdef LUA_ALLOW_BYTECODE

View file

@ -45,7 +45,8 @@ extern INT32 lua_lumploading; // is LUA_LoadLump being called?
int LUA_GetErrorMessage(lua_State *L); int LUA_GetErrorMessage(lua_State *L);
int LUA_Call(lua_State *L, int nargs, int nresults, int errorhandlerindex); 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 #ifdef LUA_ALLOW_BYTECODE
void LUA_DumpFile(const char *filename); void LUA_DumpFile(const char *filename);
#endif #endif

View file

@ -208,7 +208,7 @@ static void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile)
posStart = W_CheckNumForFullNamePK3("Init.lua", wadnum, 0); posStart = W_CheckNumForFullNamePK3("Init.lua", wadnum, 0);
if (posStart != INT16_MAX) if (posStart != INT16_MAX)
{ {
LUA_LoadLump(wadnum, posStart, true); LUA_DoLump(wadnum, posStart, true);
} }
else else
{ {
@ -217,7 +217,7 @@ static void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile)
{ {
posEnd = W_CheckNumForFolderEndPK3("Lua/", wadnum, posStart); posEnd = W_CheckNumForFolderEndPK3("Lua/", wadnum, posStart);
for (; posStart < posEnd; posStart++) for (; posStart < posEnd; posStart++)
LUA_LoadLump(wadnum, posStart, true); LUA_DoLump(wadnum, posStart, true);
} }
} }
@ -250,7 +250,7 @@ static void W_LoadDehackedLumps(UINT16 wadnum, boolean mainfile)
lumpinfo_t *lump_p = wadfiles[wadnum]->lumpinfo; lumpinfo_t *lump_p = wadfiles[wadnum]->lumpinfo;
for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++) for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++)
if (memcmp(lump_p->name,"LUA_",4)==0) if (memcmp(lump_p->name,"LUA_",4)==0)
LUA_LoadLump(wadnum, lump, true); LUA_DoLump(wadnum, lump, true);
} }
{ {
@ -993,7 +993,7 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
DEH_LoadDehackedLumpPwad(numwadfiles - 1, 0, mainfile); DEH_LoadDehackedLumpPwad(numwadfiles - 1, 0, mainfile);
break; break;
case RET_LUA: case RET_LUA:
LUA_LoadLump(numwadfiles - 1, 0, true); LUA_DoLump(numwadfiles - 1, 0, true);
break; break;
default: default:
break; break;