Created lua_blockmaplib.c, for Lua's blockmap library

my P_SearchBlockmap_* functions are now a single searchBlockmap function, you can choose between "objects" and "lines" with the first arg to decide what to iterate through. I also rearranged the argument order a bit for easy stack cleanup etc

I'll remove the old stuff later, don't worry, it's disabled for now
This commit is contained in:
Monster Iestyn 2016-10-27 18:10:30 +01:00
parent 60dcfd1021
commit dc1e7165f7
11 changed files with 277 additions and 1 deletions

View File

@ -2561,6 +2561,21 @@ HW3SOUND for 3D hardware sound support
<Option target="Debug Mingw64/DirectX" />
<Option target="Release Mingw64/DirectX" />
</Unit>
<Unit filename="src/lua_blockmaplib.c">
<Option compilerVar="CC" />
<Option target="Debug Native/SDL" />
<Option target="Release Native/SDL" />
<Option target="Debug Mingw/SDL" />
<Option target="Release Mingw/SDL" />
<Option target="Debug Mingw/DirectX" />
<Option target="Release Mingw/DirectX" />
<Option target="Debug Linux/SDL" />
<Option target="Release Linux/SDL" />
<Option target="Debug Mingw64/SDL" />
<Option target="Release Mingw64/SDL" />
<Option target="Debug Mingw64/DirectX" />
<Option target="Release Mingw64/DirectX" />
</Unit>
<Unit filename="src/lua_consolelib.c">
<Option compilerVar="CC" />
<Option target="Debug Native/SDL" />

View File

@ -231,6 +231,7 @@ if(${SRB2_CONFIG_HAVE_BLUA})
add_definitions(-DHAVE_BLUA)
set(SRB2_LUA_SOURCES
lua_baselib.c
lua_blockmaplib.c
lua_consolelib.c
lua_hooklib.c
lua_hudlib.c

View File

@ -48,4 +48,5 @@ OBJS:=$(OBJS) \
$(OBJDIR)/lua_skinlib.o \
$(OBJDIR)/lua_thinkerlib.o \
$(OBJDIR)/lua_maplib.o \
$(OBJDIR)/lua_blockmaplib.o \
$(OBJDIR)/lua_hudlib.o

View File

@ -28,7 +28,8 @@
#define NOHUD if (hud_running) return luaL_error(L, "HUD rendering code should not call this function!");
// uncomment if you want to test
#define LUA_BLOCKMAP
// note: now outdated
//#define LUA_BLOCKMAP
boolean luaL_checkboolean(lua_State *L, int narg) {
luaL_checktype(L, narg, LUA_TBOOLEAN);

248
src/lua_blockmaplib.c Normal file
View File

@ -0,0 +1,248 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2016 by Iestyn "Monster Iestyn" Jealous.
// Copyright (C) 2016 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file lua_blockmaplib.c
/// \brief blockmap library for Lua scripting
#include "doomdef.h"
#ifdef HAVE_BLUA
#include "p_local.h"
#include "r_main.h" // validcount
#include "lua_script.h"
#include "lua_libs.h"
//#include "lua_hud.h" // hud_running errors
static const char *const search_opt[] = {
"objects",
"lines",
NULL};
// a quickly-made function pointer typedef used by lib_searchBlockmap...
typedef boolean (*blockmap_func)(lua_State *, INT32, INT32, mobj_t *);
static boolean blockfuncerror = false; // errors should only print once per search blockmap call
// Helper function for "objects" search
static boolean lib_searchBlockmap_Objects(lua_State *L, INT32 x, INT32 y, mobj_t *thing)
{
mobj_t *mobj, *bnext = NULL;
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
return true;
// Check interaction with the objects in the blockmap.
for (mobj = blocklinks[y*bmapwidth + x]; mobj; mobj = bnext)
{
P_SetTarget(&bnext, mobj->bnext); // We want to note our reference to bnext here incase it is MF_NOTHINK and gets removed!
if (mobj == thing)
continue; // our thing just found itself, so move on
lua_pushvalue(L, 1); // push function
LUA_PushUserdata(L, thing, META_MOBJ);
LUA_PushUserdata(L, mobj, META_MOBJ);
if (lua_pcall(gL, 2, 1, 0)) {
if (!blockfuncerror || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
blockfuncerror = true;
return true;
}
if (!lua_isnil(gL, -1))
{ // if nil, continue
if (lua_toboolean(gL, -1))
return false;
}
lua_pop(gL, 1);
if (P_MobjWasRemoved(thing) // func just popped our thing, cannot continue.
|| (bnext && P_MobjWasRemoved(bnext))) // func just broke blockmap chain, cannot continue.
{
P_SetTarget(&bnext, NULL);
return true;
}
}
return true;
}
// Helper function for "lines" search
static boolean lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *thing)
{
INT32 offset;
const INT32 *list; // Big blockmap
#ifdef POLYOBJECTS
polymaplink_t *plink; // haleyjd 02/22/06
#endif
line_t *ld;
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
return true;
offset = y*bmapwidth + x;
#ifdef POLYOBJECTS
// haleyjd 02/22/06: consider polyobject lines
plink = polyblocklinks[offset];
while (plink)
{
polyobj_t *po = plink->po;
if (po->validcount != validcount) // if polyobj hasn't been checked
{
size_t i;
po->validcount = validcount;
for (i = 0; i < po->numLines; ++i)
{
if (po->lines[i]->validcount == validcount) // line has been checked
continue;
po->lines[i]->validcount = validcount;
lua_pushvalue(L, 1);
LUA_PushUserdata(L, thing, META_MOBJ);
LUA_PushUserdata(L, po->lines[i], META_LINE);
if (lua_pcall(gL, 2, 1, 0)) {
if (!blockfuncerror || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
blockfuncerror = true;
return true;
}
if (!lua_isnil(gL, -1))
{ // if nil, continue
if (lua_toboolean(gL, -1))
return false;
}
lua_pop(gL, 1);
if (P_MobjWasRemoved(thing))
return true;
}
}
plink = (polymaplink_t *)(plink->link.next);
}
#endif
offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x];
// First index is really empty, so +1 it.
for (list = blockmaplump + offset + 1; *list != -1; list++)
{
ld = &lines[*list];
if (ld->validcount == validcount)
continue; // Line has already been checked.
ld->validcount = validcount;
lua_pushvalue(L, 1);
LUA_PushUserdata(L, thing, META_MOBJ);
LUA_PushUserdata(L, ld, META_LINE);
if (lua_pcall(gL, 2, 1, 0)) {
if (!blockfuncerror || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
blockfuncerror = true;
return true;
}
if (!lua_isnil(gL, -1))
{ // if nil, continue
if (lua_toboolean(gL, -1))
return false;
}
lua_pop(gL, 1);
if (P_MobjWasRemoved(thing))
return true;
}
return true; // Everything was checked.
}
// The searchBlockmap function
// arguments: searchBlockmap(searchtype, function, mobj, [x1, x2, y1, y2])
// return value:
// true = search completely uninteruppted,
// false = searching of at least one block stopped mid-way (doesn't stop the whole search though)
static int lib_searchBlockmap(lua_State *L)
{
int searchtype = luaL_checkoption(L, 1, "objects", search_opt);
int n;
mobj_t *mobj;
INT32 xl, xh, yl, yh, bx, by;
fixed_t x1, x2, y1, y2;
boolean retval = true;
blockmap_func searchFunc;
lua_remove(L, 1); // remove searchtype, stack is now function, mobj, [x1, x2, y1, y2]
luaL_checktype(L, 1, LUA_TFUNCTION);
switch (searchtype)
{
case 0: // "objects"
default:
searchFunc = lib_searchBlockmap_Objects;
break;
case 1: // "lines"
searchFunc = lib_searchBlockmap_Lines;
break;
}
// the mobj we are searching around, the "calling" mobj we could say
mobj = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
if (!mobj)
return LUA_ErrInvalid(L, "mobj_t");
n = lua_gettop(L);
if (n > 2) // specific x/y ranges have been supplied
{
if (n < 6)
return luaL_error(L, "arguments 4 to 6 not all given (expected 4 fixed-point integers)");
x1 = luaL_checkfixed(L, 3);
x2 = luaL_checkfixed(L, 4);
y1 = luaL_checkfixed(L, 5);
y2 = luaL_checkfixed(L, 6);
}
else // mobj and function only - search around mobj's radius by default
{
fixed_t radius = mobj->radius + MAXRADIUS;
x1 = mobj->x - radius;
x2 = mobj->x + radius;
y1 = mobj->y - radius;
y2 = mobj->y + radius;
}
lua_settop(L, 2); // pop everything except function, mobj
xl = (unsigned)(x1 - bmaporgx)>>MAPBLOCKSHIFT;
xh = (unsigned)(x2 - bmaporgx)>>MAPBLOCKSHIFT;
yl = (unsigned)(y1 - bmaporgy)>>MAPBLOCKSHIFT;
yh = (unsigned)(y2 - bmaporgy)>>MAPBLOCKSHIFT;
BMBOUNDFIX(xl, xh, yl, yh);
blockfuncerror = false; // reset
validcount++;
for (bx = xl; bx <= xh; bx++)
for (by = yl; by <= yh; by++)
{
if (!searchFunc(L, bx, by, mobj))
retval = false;
if (P_MobjWasRemoved(mobj)){
lua_pushboolean(L, false);
return 1;
}
}
lua_pushboolean(L, retval);
return 1;
}
int LUA_BlockmapLib(lua_State *L)
{
lua_register(L, "searchBlockmap", lib_searchBlockmap);
return 0;
}
#endif

View File

@ -70,6 +70,7 @@ int LUA_PlayerLib(lua_State *L);
int LUA_SkinLib(lua_State *L);
int LUA_ThinkerLib(lua_State *L);
int LUA_MapLib(lua_State *L);
int LUA_BlockmapLib(lua_State *L);
int LUA_HudLib(lua_State *L);
#endif

View File

@ -48,6 +48,7 @@ static lua_CFunction liblist[] = {
LUA_SkinLib, // skin_t, skins[]
LUA_ThinkerLib, // thinker_t
LUA_MapLib, // line_t, side_t, sector_t, subsector_t
LUA_BlockmapLib, // blockmap stuff
LUA_HudLib, // HUD stuff
NULL
};

View File

@ -295,6 +295,7 @@
</ClCompile>
<ClCompile Include="..\i_tcp.c" />
<ClCompile Include="..\lua_baselib.c" />
<ClCompile Include="..\lua_blockmaplib.c" />
<ClCompile Include="..\lua_consolelib.c" />
<ClCompile Include="..\lua_hooklib.c" />
<ClCompile Include="..\lua_hudlib.c" />

View File

@ -633,6 +633,9 @@
<ClCompile Include="..\lua_baselib.c">
<Filter>LUA</Filter>
</ClCompile>
<ClCompile Include="..\lua_blockmaplib.c">
<Filter>LUA</Filter>
</ClCompile>
<ClCompile Include="..\lua_consolelib.c">
<Filter>LUA</Filter>
</ClCompile>

View File

@ -131,6 +131,7 @@
</ClCompile>
<ClCompile Include="..\i_tcp.c" />
<ClCompile Include="..\lua_baselib.c" />
<ClCompile Include="..\lua_blockmaplib.c" />
<ClCompile Include="..\lua_consolelib.c" />
<ClCompile Include="..\lua_hooklib.c" />
<ClCompile Include="..\lua_hudlib.c" />

View File

@ -225,6 +225,9 @@
<ClCompile Include="..\lua_baselib.c">
<Filter>LUA</Filter>
</ClCompile>
<ClCompile Include="..\lua_blockmaplib.c">
<Filter>LUA</Filter>
</ClCompile>
<ClCompile Include="..\lua_consolelib.c">
<Filter>LUA</Filter>
</ClCompile>