From 75ee3193f42524b80a8ebd26dee4d801a8106053 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 25 Sep 2019 20:27:41 +0100 Subject: [PATCH 1/4] Write a new hack for getting sector->linecount from sector->lines in Lua, to put my mind at rest about it at last. 1) In sector_get, actually push the memory address of the lines array within sector_t, rather than push the value of "lines" itself (essentially, we we want a pointer to a double pointer, or rather a TRIPLE pointer haha) 2) In the sectorlines_* functions, use offsetof to shift the memory address so we can obtain the value of linecount within the sector_t struct, and dereference the result to obtain the value of linecount itself 3) ??? profit Untested and uncompiled atm, but I have some confidence this might work --- src/lua_maplib.c | 55 ++++++++++++++++++++++++++++++------------------ src/lua_script.c | 2 +- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index dbb69b7e2..1da232efa 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -411,37 +411,53 @@ static int sector_iterate(lua_State *L) // sector.lines, i -> sector.lines[i] // sector.lines.valid, for validity checking +// +// 25/9/19 Monster Iestyn +// Modified this and _num to use triple pointers, to allow for a new hack of mine involving offsetof +// this way we don't need to check frontsector or backsector of line #0 in the array +// static int sectorlines_get(lua_State *L) { - line_t **seclines = *((line_t ***)luaL_checkudata(L, 1, META_SECTORLINES)); + line_t ***seclines = *((line_t ****)luaL_checkudata(L, 1, META_SECTORLINES)); size_t i; size_t numoflines = 0; lua_settop(L, 2); if (!lua_isnumber(L, 2)) { int field = luaL_checkoption(L, 2, NULL, valid_opt); - if (!seclines) + if (!seclines || !(*seclines)) { if (field == 0) { lua_pushboolean(L, 0); return 1; } - return luaL_error(L, "accessed sector_t doesn't exist anymore."); + return luaL_error(L, "accessed sector_t.lines doesn't exist anymore."); } else if (field == 0) { lua_pushboolean(L, 1); return 1; } } +/* a snip from sector_t struct in r_defs.h, for reference + size_t linecount; + struct line_s **lines; // [linecount] size +*/ + // get the "linecount" by shifting our retrieved memory address of "lines" to where "linecount" is in the sector_t, then dereferencing the result + // we need this to determine the array's actual size, and therefore also the maximum value allowed as an index + // this only works if seclines is actually a pointer to a sector's lines member in memory, oh boy + numoflines = (size_t)(*(seclines - (offsetof(sector_t, lines) - offsetof(sector_t, linecount)))); + +/* OLD HACK // check first linedef to figure which of its sectors owns this sector->lines pointer // then check that sector's linecount to get a maximum index - //if (!seclines[0]) + //if (!(*seclines)[0]) //return luaL_error(L, "no lines found!"); // no first linedef????? - if (seclines[0]->frontsector->lines == seclines) - numoflines = seclines[0]->frontsector->linecount; - else if (seclines[0]->backsector && seclines[0]->backsector->lines == seclines) // check backsector exists first - numoflines = seclines[0]->backsector->linecount; + if ((*seclines)[0]->frontsector->lines == *seclines) + numoflines = (*seclines)[0]->frontsector->linecount; + else if ((*seclines)[0]->backsector && *seclines[0]->backsector->lines == *seclines) // check backsector exists first + numoflines = (*seclines)[0]->backsector->linecount; //if neither sector has it then ??? +*/ if (!numoflines) return luaL_error(L, "no lines found!"); @@ -449,23 +465,21 @@ static int sectorlines_get(lua_State *L) i = (size_t)lua_tointeger(L, 2); if (i >= numoflines) return 0; - LUA_PushUserdata(L, seclines[i], META_LINE); + LUA_PushUserdata(L, (*seclines)[i], META_LINE); return 1; } +// #(sector.lines) -> sector.linecount static int sectorlines_num(lua_State *L) { - line_t **seclines = *((line_t ***)luaL_checkudata(L, 1, META_SECTORLINES)); + line_t ***seclines = *((line_t ****)luaL_checkudata(L, 1, META_SECTORLINES)); size_t numoflines = 0; - // check first linedef to figure which of its sectors owns this sector->lines pointer - // then check that sector's linecount to get a maximum index - //if (!seclines[0]) - //return luaL_error(L, "no lines found!"); // no first linedef????? - if (seclines[0]->frontsector->lines == seclines) - numoflines = seclines[0]->frontsector->linecount; - else if (seclines[0]->backsector && seclines[0]->backsector->lines == seclines) // check backsector exists first - numoflines = seclines[0]->backsector->linecount; - //if neither sector has it then ??? + + if (!seclines || !(*seclines)) + return luaL_error(L, "accessed sector_t.lines doesn't exist anymore."); + + // see comments in the _get function above + numoflines = (size_t)(*(seclines - (offsetof(sector_t, lines) - offsetof(sector_t, linecount)))); lua_pushinteger(L, numoflines); return 1; } @@ -543,7 +557,7 @@ static int sector_get(lua_State *L) LUA_PushUserdata(L, §ors[sector->camsec], META_SECTOR); return 1; case sector_lines: // lines - LUA_PushUserdata(L, sector->lines, META_SECTORLINES); + LUA_PushUserdata(L, §or->lines, META_SECTORLINES); // push the address of the "lines" member in the struct, to allow our hacks in sectorlines_get/_num to work return 1; case sector_ffloors: // ffloors lua_pushcfunction(L, lib_iterateSectorFFloors); @@ -579,6 +593,7 @@ static int sector_set(lua_State *L) case sector_thinglist: // thinglist case sector_heightsec: // heightsec case sector_camsec: // camsec + case sector_lines: // lines case sector_ffloors: // ffloors #ifdef ESLOPE case sector_fslope: // f_slope diff --git a/src/lua_script.c b/src/lua_script.c index deb644dc0..a161368b8 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -431,7 +431,7 @@ void LUA_InvalidateLevel(void) for (i = 0; i < numsectors; i++) { LUA_InvalidateUserdata(§ors[i]); - LUA_InvalidateUserdata(sectors[i].lines); + LUA_InvalidateUserdata(§ors[i].lines); if (sectors[i].ffloors) { for (rover = sectors[i].ffloors; rover; rover = rover->next) From 240aa34794864b6af6170f2322ba7805f3af99b5 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 27 Sep 2019 21:16:11 +0100 Subject: [PATCH 2/4] Added consoleplayer, displayplayer and secondarydisplayplayer, by popular request --- src/dehacked.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 8334de61a..87afa08d0 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9932,6 +9932,23 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word,"mapmusposition")) { lua_pushinteger(L, mapmusposition); return 1; + // local player variables, by popular request + } else if (fastcmp(word,"consoleplayer")) { // player controlling console (aka local player 1) + if (!playeringame[consoleplayer]) + return 0; + LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER); + return 1; + } else if (fastcmp(word,"displayplayer")) { // player visible on screen (aka display player 1) + if (!playeringame[displayplayer]) + return 0; + LUA_PushUserdata(L, &players[displayplayer], META_PLAYER); + return 1; + } else if (fastcmp(word,"secondarydisplayplayer")) { // local/display player 2, for splitscreen + if (!splitscreen || !playeringame[secondarydisplayplayer]) + return 0; + LUA_PushUserdata(L, &players[secondarydisplayplayer], META_PLAYER); + return 1; + // end local player variables } else if (fastcmp(word,"server")) { if ((!multiplayer || !netgame) && !playeringame[serverplayer]) return 0; From fa444a37eb9cd063b0ab735edce96dcae9d288a1 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 27 Sep 2019 23:15:38 +0100 Subject: [PATCH 3/4] Added < 0 checks to all three variables added in last commit (no point checking >= MAXPLAYERS tbh, there's no reason the game would even set those values that I can think of offhand) --- src/dehacked.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 87afa08d0..25f1dac65 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9934,17 +9934,17 @@ static inline int lib_getenum(lua_State *L) return 1; // local player variables, by popular request } else if (fastcmp(word,"consoleplayer")) { // player controlling console (aka local player 1) - if (!playeringame[consoleplayer]) + if (consoleplayer < 0 || !playeringame[consoleplayer]) return 0; LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER); return 1; } else if (fastcmp(word,"displayplayer")) { // player visible on screen (aka display player 1) - if (!playeringame[displayplayer]) + if (displayplayer < 0 || !playeringame[displayplayer]) return 0; LUA_PushUserdata(L, &players[displayplayer], META_PLAYER); return 1; } else if (fastcmp(word,"secondarydisplayplayer")) { // local/display player 2, for splitscreen - if (!splitscreen || !playeringame[secondarydisplayplayer]) + if (!splitscreen || secondarydisplayplayer < 0 || consoleplayer >= MAXPLAYERS || !playeringame[secondarydisplayplayer]) return 0; LUA_PushUserdata(L, &players[secondarydisplayplayer], META_PLAYER); return 1; From 52562c4125a745efd2851323896630d2df3f5727 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 28 Sep 2019 20:45:44 +0100 Subject: [PATCH 4/4] whoops, didn't mean to include this --- src/dehacked.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index 25f1dac65..aff9e8617 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9944,7 +9944,7 @@ static inline int lib_getenum(lua_State *L) LUA_PushUserdata(L, &players[displayplayer], META_PLAYER); return 1; } else if (fastcmp(word,"secondarydisplayplayer")) { // local/display player 2, for splitscreen - if (!splitscreen || secondarydisplayplayer < 0 || consoleplayer >= MAXPLAYERS || !playeringame[secondarydisplayplayer]) + if (!splitscreen || secondarydisplayplayer < 0 || !playeringame[secondarydisplayplayer]) return 0; LUA_PushUserdata(L, &players[secondarydisplayplayer], META_PLAYER); return 1;