mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-17 23:21:22 +00:00
spriteinfo lua support
This commit is contained in:
parent
e78999549b
commit
f739956e89
3 changed files with 284 additions and 2 deletions
|
@ -143,6 +143,7 @@ static const struct {
|
||||||
{META_STATE, "state_t"},
|
{META_STATE, "state_t"},
|
||||||
{META_MOBJINFO, "mobjinfo_t"},
|
{META_MOBJINFO, "mobjinfo_t"},
|
||||||
{META_SFXINFO, "sfxinfo_t"},
|
{META_SFXINFO, "sfxinfo_t"},
|
||||||
|
{META_SPRITEINFO, "spriteinfo_t"},
|
||||||
|
|
||||||
{META_MOBJ, "mobj_t"},
|
{META_MOBJ, "mobj_t"},
|
||||||
{META_MAPTHING, "mapthing_t"},
|
{META_MAPTHING, "mapthing_t"},
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#include "p_mobj.h"
|
#include "p_mobj.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
|
#include "r_patch.h"
|
||||||
|
#include "r_things.h"
|
||||||
#include "doomstat.h" // luabanks[]
|
#include "doomstat.h" // luabanks[]
|
||||||
|
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
|
@ -221,6 +223,259 @@ static int lib_spr2namelen(lua_State *L)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
// SPRITE INFO //
|
||||||
|
/////////////////
|
||||||
|
|
||||||
|
static int lib_getSpriteInfo(lua_State *L)
|
||||||
|
{
|
||||||
|
UINT32 i = 0;
|
||||||
|
lua_remove(L, 1);
|
||||||
|
|
||||||
|
/*if (lua_isstring(L, 1))
|
||||||
|
{
|
||||||
|
const char *name = lua_tostring(L, 1);
|
||||||
|
INT32 spr;
|
||||||
|
CONS_Printf("%s\n",name);
|
||||||
|
for (spr = 0; spr < NUMSPRITES; spr++)
|
||||||
|
{
|
||||||
|
if (fastcmp(name, sprnames[spr]))
|
||||||
|
{
|
||||||
|
i = spr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else*/
|
||||||
|
i = luaL_checkinteger(L, 1);
|
||||||
|
|
||||||
|
if (i == 0 || i >= NUMSPRITES)
|
||||||
|
return luaL_error(L, "spriteinfo[] index %d out of range (1 - %d)", i, NUMSPRITES-1);
|
||||||
|
|
||||||
|
LUA_PushUserdata(L, &spriteinfo[i], META_SPRITEINFO);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FIELDERROR(f, e) luaL_error(L, "bad value for " LUA_QL(f) " in table passed to spriteinfo[] (%s)", e);
|
||||||
|
#define TYPEERROR(f, t1, t2) FIELDERROR(f, va("%s expected, got %s", lua_typename(L, t1), lua_typename(L, t2)))
|
||||||
|
|
||||||
|
#ifdef ROTSPRITE
|
||||||
|
static int PopPivotTable(spriteinfo_t *info, lua_State *L, int stk)
|
||||||
|
{
|
||||||
|
// Just in case?
|
||||||
|
if (!lua_istable(L, stk))
|
||||||
|
TYPEERROR("pivot table", LUA_TTABLE, lua_type(L, stk));
|
||||||
|
|
||||||
|
lua_pushnil(L);
|
||||||
|
// stk = 0 has the pivot table
|
||||||
|
// stk = 1 has the frame key
|
||||||
|
// stk = 2 has the frame table
|
||||||
|
// stk = 3 has either "x" or "y" or a number as key
|
||||||
|
// stk = 4 has the value for the key mentioned above
|
||||||
|
while (lua_next(L, stk))
|
||||||
|
{
|
||||||
|
int idx = 0;
|
||||||
|
const char *framestr = NULL;
|
||||||
|
switch (lua_type(L, stk+1))
|
||||||
|
{
|
||||||
|
case LUA_TSTRING:
|
||||||
|
framestr = lua_tostring(L, stk+1);
|
||||||
|
idx = R_Char2Frame(framestr[0]);
|
||||||
|
break;
|
||||||
|
case LUA_TNUMBER:
|
||||||
|
idx = lua_tonumber(L, stk+1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
TYPEERROR("pivot frame", LUA_TNUMBER, lua_type(L, stk+1));
|
||||||
|
}
|
||||||
|
if ((idx < 0) || (idx >= 64))
|
||||||
|
return luaL_error(L, "pivot frame %d out of range (0 - %d)", idx, 63);
|
||||||
|
// the values in pivot[] are also tables
|
||||||
|
switch (lua_type(L, stk+2))
|
||||||
|
{
|
||||||
|
case LUA_TTABLE:
|
||||||
|
lua_pushnil(L);
|
||||||
|
while (lua_next(L, stk+2))
|
||||||
|
{
|
||||||
|
const char *key = NULL;
|
||||||
|
lua_Integer ikey = -1;
|
||||||
|
lua_Integer value = 0;
|
||||||
|
// x or y?
|
||||||
|
switch (lua_type(L, stk+3))
|
||||||
|
{
|
||||||
|
case LUA_TSTRING:
|
||||||
|
key = lua_tostring(L, stk+3);
|
||||||
|
break;
|
||||||
|
case LUA_TNUMBER:
|
||||||
|
ikey = lua_tointeger(L, stk+3);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
FIELDERROR("pivot key", va("string or number expected, got %s", luaL_typename(L, stk+3)))
|
||||||
|
}
|
||||||
|
// then get value
|
||||||
|
switch (lua_type(L, stk+4))
|
||||||
|
{
|
||||||
|
case LUA_TNUMBER:
|
||||||
|
value = lua_tonumber(L, stk+4);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
TYPEERROR("pivot value", LUA_TNUMBER, lua_type(L, stk+4))
|
||||||
|
}
|
||||||
|
// finally set omg!!!!!!!!!!!!!!!!!!
|
||||||
|
if (ikey == 1 || (key && fastcmp(key, "x")))
|
||||||
|
info->pivot[idx].x = (INT32)value;
|
||||||
|
else if (ikey == 2 || (key && fastcmp(key, "y")))
|
||||||
|
info->pivot[idx].y = (INT32)value;
|
||||||
|
else if (ikey == -1 && (key != NULL))
|
||||||
|
FIELDERROR("pivot key", va("x or y expected, got %s", key));
|
||||||
|
info->available = true; // the pivot for this frame is available
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
TYPEERROR("sprite pivot", LUA_TTABLE, lua_type(L, stk+2))
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int lib_setSpriteInfo(lua_State *L)
|
||||||
|
{
|
||||||
|
spriteinfo_t *info;
|
||||||
|
|
||||||
|
lua_remove(L, 1);
|
||||||
|
{
|
||||||
|
UINT32 i = luaL_checkinteger(L, 1);
|
||||||
|
if (i == 0 || i >= NUMSPRITES)
|
||||||
|
return luaL_error(L, "spriteinfo[] index %d out of range (1 - %d)", i, NUMSPRITES-1);
|
||||||
|
info = &spriteinfo[i]; // get the sfxinfo to assign to.
|
||||||
|
}
|
||||||
|
luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table.
|
||||||
|
lua_remove(L, 1); // pop sprite num, don't need it any more.
|
||||||
|
lua_settop(L, 1); // cut the stack here. the only thing left now is the table of data we're assigning to the spriteinfo.
|
||||||
|
|
||||||
|
if (!lua_lumploading)
|
||||||
|
return luaL_error(L, "Do not alter spriteinfo_t from within a hook or coroutine!");
|
||||||
|
if (hud_running)
|
||||||
|
return luaL_error(L, "Do not alter spriteinfo_t in HUD rendering code!");
|
||||||
|
|
||||||
|
lua_pushnil(L);
|
||||||
|
while (lua_next(L, 1)) {
|
||||||
|
lua_Integer i = 0;
|
||||||
|
const char *str = NULL;
|
||||||
|
if (lua_isnumber(L, 2))
|
||||||
|
{
|
||||||
|
i = lua_tointeger(L, 2);
|
||||||
|
#ifndef ROTSPRITE
|
||||||
|
i++; // shift index in case of missing rotsprite support
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
str = luaL_checkstring(L, 2);
|
||||||
|
|
||||||
|
#ifdef ROTSPRITE
|
||||||
|
if (i == 1 || (str && fastcmp(str, "pivot")))
|
||||||
|
{
|
||||||
|
// pivot[] is a table
|
||||||
|
if (lua_istable(L, 3))
|
||||||
|
return PopPivotTable(info, L, 3);
|
||||||
|
else
|
||||||
|
FIELDERROR("pivot", va("%s expected, got %s", lua_typename(L, LUA_TTABLE), luaL_typename(L, -1)))
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef FIELDERROR
|
||||||
|
#undef TYPEERROR
|
||||||
|
|
||||||
|
static int lib_spriteinfolen(lua_State *L)
|
||||||
|
{
|
||||||
|
lua_pushinteger(L, NUMSPRITES);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int spriteinfo_get(lua_State *L)
|
||||||
|
{
|
||||||
|
spriteinfo_t *sprinfo = *((spriteinfo_t **)luaL_checkudata(L, 1, META_SPRITEINFO));
|
||||||
|
const char *field = luaL_checkstring(L, 2);
|
||||||
|
|
||||||
|
I_Assert(sprinfo != NULL);
|
||||||
|
|
||||||
|
#ifdef ROTSPRITE
|
||||||
|
// push a table with the contents of spriteinfo_t->pivot
|
||||||
|
if (fastcmp(field, "pivot"))
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char c[2] = "";
|
||||||
|
lua_newtable(L);
|
||||||
|
|
||||||
|
for (i = 0; i < 64; i++)
|
||||||
|
{
|
||||||
|
c[0] = R_Frame2Char(i);
|
||||||
|
c[1] = 0;
|
||||||
|
lua_pushstring(L, c);
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_pushnumber(L, sprinfo->pivot[i].x);
|
||||||
|
lua_setfield(L, -2, "x");
|
||||||
|
lua_pushnumber(L, sprinfo->pivot[i].y);
|
||||||
|
lua_setfield(L, -2, "y");
|
||||||
|
lua_settable(L, -3);
|
||||||
|
}
|
||||||
|
// the table is now on the top of the stack
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
return luaL_error(L, LUA_QL("spriteinfo_t") " has no field named " LUA_QS, field);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int spriteinfo_set(lua_State *L)
|
||||||
|
{
|
||||||
|
spriteinfo_t *sprinfo = *((spriteinfo_t **)luaL_checkudata(L, 1, META_SPRITEINFO));
|
||||||
|
const char *field = luaL_checkstring(L, 2);
|
||||||
|
|
||||||
|
if (!lua_lumploading)
|
||||||
|
return luaL_error(L, "Do not alter spriteinfo_t from within a hook or coroutine!");
|
||||||
|
if (hud_running)
|
||||||
|
return luaL_error(L, "Do not alter spriteinfo_t in HUD rendering code!");
|
||||||
|
|
||||||
|
I_Assert(sprinfo != NULL);
|
||||||
|
|
||||||
|
lua_remove(L, 1); // remove spriteinfo
|
||||||
|
lua_remove(L, 1); // remove field
|
||||||
|
lua_settop(L, 1); // leave only one value
|
||||||
|
|
||||||
|
#ifdef ROTSPRITE
|
||||||
|
if (fastcmp(field, "pivot"))
|
||||||
|
return PopPivotTable(sprinfo, L, 1);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
return luaL_error(L, va("Field %s does not exist in spriteinfo_t", field));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int spriteinfo_num(lua_State *L)
|
||||||
|
{
|
||||||
|
spriteinfo_t *sprinfo = *((spriteinfo_t **)luaL_checkudata(L, 1, META_SFXINFO));
|
||||||
|
|
||||||
|
I_Assert(sprinfo != NULL);
|
||||||
|
I_Assert(sprinfo >= spriteinfo);
|
||||||
|
|
||||||
|
lua_pushinteger(L, (UINT32)(sprinfo-spriteinfo));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////
|
////////////////
|
||||||
// STATE INFO //
|
// STATE INFO //
|
||||||
////////////////
|
////////////////
|
||||||
|
@ -903,8 +1158,8 @@ static int lib_setSfxInfo(lua_State *L)
|
||||||
info = &S_sfx[i]; // get the sfxinfo to assign to.
|
info = &S_sfx[i]; // get the sfxinfo to assign to.
|
||||||
}
|
}
|
||||||
luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table.
|
luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table.
|
||||||
lua_remove(L, 1); // pop mobjtype num, don't need it any more.
|
lua_remove(L, 1); // pop sfx num, don't need it any more.
|
||||||
lua_settop(L, 1); // cut the stack here. the only thing left now is the table of data we're assigning to the mobjinfo.
|
lua_settop(L, 1); // cut the stack here. the only thing left now is the table of data we're assigning to the sfx.
|
||||||
|
|
||||||
if (hud_running)
|
if (hud_running)
|
||||||
return luaL_error(L, "Do not alter sfxinfo in HUD rendering code!");
|
return luaL_error(L, "Do not alter sfxinfo in HUD rendering code!");
|
||||||
|
@ -1130,6 +1385,17 @@ int LUA_InfoLib(lua_State *L)
|
||||||
lua_setfield(L, -2, "__len");
|
lua_setfield(L, -2, "__len");
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
luaL_newmetatable(L, META_SPRITEINFO);
|
||||||
|
lua_pushcfunction(L, spriteinfo_get);
|
||||||
|
lua_setfield(L, -2, "__index");
|
||||||
|
|
||||||
|
lua_pushcfunction(L, spriteinfo_set);
|
||||||
|
lua_setfield(L, -2, "__newindex");
|
||||||
|
|
||||||
|
lua_pushcfunction(L, spriteinfo_num);
|
||||||
|
lua_setfield(L, -2, "__len");
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
lua_newuserdata(L, 0);
|
lua_newuserdata(L, 0);
|
||||||
lua_createtable(L, 0, 2);
|
lua_createtable(L, 0, 2);
|
||||||
lua_pushcfunction(L, lib_getSprname);
|
lua_pushcfunction(L, lib_getSprname);
|
||||||
|
@ -1204,6 +1470,20 @@ int LUA_InfoLib(lua_State *L)
|
||||||
lua_setglobal(L, "S_sfx");
|
lua_setglobal(L, "S_sfx");
|
||||||
lua_setglobal(L, "sfxinfo");
|
lua_setglobal(L, "sfxinfo");
|
||||||
|
|
||||||
|
lua_newuserdata(L, 0);
|
||||||
|
lua_createtable(L, 0, 2);
|
||||||
|
lua_pushcfunction(L, lib_getSpriteInfo);
|
||||||
|
lua_setfield(L, -2, "__index");
|
||||||
|
|
||||||
|
lua_pushcfunction(L, lib_setSpriteInfo);
|
||||||
|
lua_setfield(L, -2, "__newindex");
|
||||||
|
|
||||||
|
lua_pushcfunction(L, lib_spriteinfolen);
|
||||||
|
lua_setfield(L, -2, "__len");
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
lua_pushvalue(L, -1);
|
||||||
|
lua_setglobal(L, "spriteinfo");
|
||||||
|
|
||||||
luaL_newmetatable(L, META_LUABANKS);
|
luaL_newmetatable(L, META_LUABANKS);
|
||||||
lua_pushcfunction(L, lib_getluabanks);
|
lua_pushcfunction(L, lib_getluabanks);
|
||||||
lua_setfield(L, -2, "__index");
|
lua_setfield(L, -2, "__index");
|
||||||
|
|
|
@ -22,6 +22,7 @@ extern lua_State *gL;
|
||||||
#define META_STATE "STATE_T*"
|
#define META_STATE "STATE_T*"
|
||||||
#define META_MOBJINFO "MOBJINFO_T*"
|
#define META_MOBJINFO "MOBJINFO_T*"
|
||||||
#define META_SFXINFO "SFXINFO_T*"
|
#define META_SFXINFO "SFXINFO_T*"
|
||||||
|
#define META_SPRITEINFO "SPRITEINFO_T*"
|
||||||
|
|
||||||
#define META_MOBJ "MOBJ_T*"
|
#define META_MOBJ "MOBJ_T*"
|
||||||
#define META_MAPTHING "MAPTHING_T*"
|
#define META_MAPTHING "MAPTHING_T*"
|
||||||
|
|
Loading…
Reference in a new issue