mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-18 07:22:28 +00:00
Added node_t and nodes[] to Lua
Still some issues with node.bbox, but the rest seems to work
This commit is contained in:
parent
88a805b331
commit
4c723d05ac
3 changed files with 259 additions and 0 deletions
|
@ -39,12 +39,17 @@ extern lua_State *gL;
|
|||
#define META_SECTOR "SECTOR_T*"
|
||||
#define META_FFLOOR "FFLOOR_T*"
|
||||
#define META_SEG "SEG_T*"
|
||||
#define META_NODE "NODE_T*"
|
||||
#define META_MAPHEADER "MAPHEADER_T*"
|
||||
|
||||
#define META_CVAR "CONSVAR_T*"
|
||||
|
||||
#define META_SECTORLINES "SECTOR_T*LINES"
|
||||
#define META_SIDENUM "LINE_T*SIDENUM"
|
||||
#define META_NODEBBOX "NODE_T*BBOX"
|
||||
#define META_NODECHILDREN "NODE_T*CHILDREN"
|
||||
|
||||
#define META_BBOX "BOUNDING_BOX"
|
||||
|
||||
#define META_HUDINFO "HUDINFO_T*"
|
||||
#define META_PATCH "PATCH_T*"
|
||||
|
|
238
src/lua_maplib.c
238
src/lua_maplib.c
|
@ -211,6 +211,26 @@ static const char *const seg_opt[] = {
|
|||
"backsector",
|
||||
NULL};
|
||||
|
||||
enum node_e {
|
||||
node_valid = 0,
|
||||
node_x,
|
||||
node_y,
|
||||
node_dx,
|
||||
node_dy,
|
||||
node_bbox,
|
||||
node_children,
|
||||
};
|
||||
|
||||
static const char *const node_opt[] = {
|
||||
"valid",
|
||||
"x",
|
||||
"y",
|
||||
"dx",
|
||||
"dy",
|
||||
"bbox",
|
||||
"children",
|
||||
NULL};
|
||||
|
||||
static const char *const array_opt[] ={"iterate",NULL};
|
||||
static const char *const valid_opt[] ={"valid",NULL};
|
||||
|
||||
|
@ -901,6 +921,145 @@ static int seg_num(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int node_get(lua_State *L)
|
||||
{
|
||||
node_t *node = *((node_t **)luaL_checkudata(L, 1, META_NODE));
|
||||
enum node_e field = luaL_checkoption(L, 2, node_opt[0], node_opt);
|
||||
|
||||
if (!node)
|
||||
{
|
||||
if (field == node_valid) {
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
return luaL_error(L, "accessed node_t doesn't exist anymore.");
|
||||
}
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case node_valid: // valid
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
case node_x:
|
||||
lua_pushfixed(L, node->x);
|
||||
return 1;
|
||||
case node_y:
|
||||
lua_pushfixed(L, node->y);
|
||||
return 1;
|
||||
case node_dx:
|
||||
lua_pushfixed(L, node->x);
|
||||
return 1;
|
||||
case node_dy:
|
||||
lua_pushfixed(L, node->x);
|
||||
return 1;
|
||||
case node_bbox:
|
||||
LUA_PushUserdata(L, node->bbox, META_NODEBBOX);
|
||||
return 1;
|
||||
case node_children:
|
||||
LUA_PushUserdata(L, node->children, META_NODECHILDREN);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int node_num(lua_State *L)
|
||||
{
|
||||
node_t *node = *((node_t **)luaL_checkudata(L, 1, META_NODE));
|
||||
lua_pushinteger(L, node-nodes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// node.bbox[i][j]: i = 0 or 1, j = 0 1 2 or 3
|
||||
// NOTE: 2D arrays are NOT double pointers,
|
||||
// the second bbox will be directly after the first in memory (hence the way the bbox is pushed here)
|
||||
// this function handles the [i] part, bbox_get handles the [j] part
|
||||
static int nodebbox_get(lua_State *L)
|
||||
{
|
||||
fixed_t *bbox = *((fixed_t **)luaL_checkudata(L, 1, META_NODEBBOX));
|
||||
int i;
|
||||
lua_settop(L, 2);
|
||||
if (!lua_isnumber(L, 2))
|
||||
{
|
||||
int field = luaL_checkoption(L, 2, NULL, valid_opt);
|
||||
if (!bbox)
|
||||
{
|
||||
if (field == 0) {
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
return luaL_error(L, "accessed node_t doesn't exist anymore.");
|
||||
} else if (field == 0) {
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
i = lua_tointeger(L, 2);
|
||||
if (i < 0 || i > 1)
|
||||
return 0;
|
||||
LUA_PushUserdata(L, bbox + i*4*sizeof(fixed_t), META_BBOX);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// node.children[i]: i = 0 or 1
|
||||
static int nodechildren_get(lua_State *L)
|
||||
{
|
||||
UINT16 *children = *((UINT16 **)luaL_checkudata(L, 1, META_NODECHILDREN));
|
||||
int i;
|
||||
lua_settop(L, 2);
|
||||
if (!lua_isnumber(L, 2))
|
||||
{
|
||||
int field = luaL_checkoption(L, 2, NULL, valid_opt);
|
||||
if (!children)
|
||||
{
|
||||
if (field == 0) {
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
return luaL_error(L, "accessed node_t doesn't exist anymore.");
|
||||
} else if (field == 0) {
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
i = lua_tointeger(L, 2);
|
||||
if (i < 0 || i > 1)
|
||||
return 0;
|
||||
lua_pushinteger(L, children[i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// bounding box (aka fixed_t array with four elements)
|
||||
// NOTE: may be useful for polyobjects or other things later
|
||||
static int bbox_get(lua_State *L)
|
||||
{
|
||||
fixed_t *bbox = *((fixed_t **)luaL_checkudata(L, 1, META_BBOX));
|
||||
int i;
|
||||
lua_settop(L, 2);
|
||||
if (!lua_isnumber(L, 2))
|
||||
{
|
||||
int field = luaL_checkoption(L, 2, NULL, valid_opt);
|
||||
if (!bbox)
|
||||
{
|
||||
if (field == 0) {
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
return luaL_error(L, "accessed node_t doesn't exist anymore.");
|
||||
} else if (field == 0) {
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
i = lua_tointeger(L, 2);
|
||||
if (i < 0 || i > 3)
|
||||
return 0;
|
||||
lua_pushinteger(L, bbox[i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_iterateSectors(lua_State *L)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
@ -1177,6 +1336,52 @@ static int lib_numsegs(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int lib_iterateNodes(lua_State *L)
|
||||
{
|
||||
size_t i = 0;
|
||||
if (lua_gettop(L) < 2)
|
||||
return luaL_error(L, "Don't call nodes.iterate() directly, use it as 'for node in nodes.iterate do <block> end'.");
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // state is unused.
|
||||
if (!lua_isnil(L, 1))
|
||||
i = (size_t)(*((node_t **)luaL_checkudata(L, 1, META_NODE)) - nodes)+1;
|
||||
if (i < numsegs)
|
||||
{
|
||||
LUA_PushUserdata(L, &nodes[i], META_NODE);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_getNode(lua_State *L)
|
||||
{
|
||||
int field;
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // dummy userdata table is unused.
|
||||
if (lua_isnumber(L, 1))
|
||||
{
|
||||
size_t i = lua_tointeger(L, 1);
|
||||
if (i >= numnodes)
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &nodes[i], META_NODE);
|
||||
return 1;
|
||||
}
|
||||
field = luaL_checkoption(L, 1, NULL, array_opt);
|
||||
switch(field)
|
||||
{
|
||||
case 0: // iterate
|
||||
lua_pushcfunction(L, lib_iterateNodes);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_numnodes(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, numnodes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ffloor_get(lua_State *L)
|
||||
{
|
||||
ffloor_t *ffloor = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR));
|
||||
|
@ -1504,6 +1709,29 @@ int LUA_MapLib(lua_State *L)
|
|||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_NODE);
|
||||
lua_pushcfunction(L, node_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, node_num);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_NODEBBOX);
|
||||
lua_pushcfunction(L, nodebbox_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_NODECHILDREN);
|
||||
lua_pushcfunction(L, nodechildren_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_BBOX);
|
||||
lua_pushcfunction(L, bbox_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_MAPHEADER);
|
||||
lua_pushcfunction(L, mapheaderinfo_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
@ -1572,6 +1800,16 @@ int LUA_MapLib(lua_State *L)
|
|||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "segs");
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getNode);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, lib_numnodes);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "nodes");
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getMapheaderinfo);
|
||||
|
|
|
@ -456,6 +456,7 @@ enum
|
|||
ARCH_SUBSECTOR,
|
||||
ARCH_SECTOR,
|
||||
ARCH_SEG,
|
||||
ARCH_NODE,
|
||||
ARCH_MAPHEADER,
|
||||
|
||||
ARCH_TEND=0xFF,
|
||||
|
@ -476,6 +477,7 @@ static const struct {
|
|||
{META_SUBSECTOR,ARCH_SUBSECTOR},
|
||||
{META_SECTOR, ARCH_SECTOR},
|
||||
{META_SEG, ARCH_SEG},
|
||||
{META_NODE, ARCH_NODE},
|
||||
{META_MAPHEADER, ARCH_MAPHEADER},
|
||||
{NULL, ARCH_NULL}
|
||||
};
|
||||
|
@ -677,6 +679,17 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case ARCH_NODE:
|
||||
{
|
||||
node_t *node = *((node_t **)lua_touserdata(gL, myindex));
|
||||
if (!node)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_NODE);
|
||||
WRITEUINT16(save_p, node - nodes);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ARCH_MAPHEADER:
|
||||
{
|
||||
mapheader_t *header = *((mapheader_t **)lua_touserdata(gL, myindex));
|
||||
|
@ -858,6 +871,9 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
|
|||
case ARCH_SEG:
|
||||
LUA_PushUserdata(gL, &segs[READUINT16(save_p)], META_SEG);
|
||||
break;
|
||||
case ARCH_NODE:
|
||||
LUA_PushUserdata(gL, &nodes[READUINT16(save_p)], META_NODE);
|
||||
break;
|
||||
case ARCH_MAPHEADER:
|
||||
LUA_PushUserdata(gL, §ors[READUINT16(save_p)], META_MAPHEADER);
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue