Merge branch 'issue1157' into 'next'

Add Lua bindings for MUSICDEF (read-only, of course)

See merge request STJr/SRB2!2367
This commit is contained in:
SSNTails 2025-03-21 13:17:22 +00:00
commit 9871aeec49
4 changed files with 101 additions and 0 deletions

View file

@ -189,6 +189,8 @@ static const struct {
{META_SKINSPRITESLIST, "skin_t.skinsprites[]"},
{META_SKINSPRITESCOMPAT, "skin_t.sprites"}, // TODO: 2.3: Delete
{META_MUSICDEF, "musicdef_t"},
{META_VERTEX, "vertex_t"},
{META_LINE, "line_t"},
{META_SIDE, "side_t"},
@ -3738,6 +3740,73 @@ static int lib_sResumeMusic(lua_State *L)
return 1;
}
enum musicdef_e
{
musicdef_name,
musicdef_title,
musicdef_alttitle,
musicdef_authors
};
static const char *const musicdef_opt[] = {
"name",
"title",
"alttitle",
"authors",
NULL,
};
static int musicdef_fields_ref = LUA_NOREF;
static int musicdef_get(lua_State *L)
{
musicdef_t *musicdef = *((musicdef_t **)luaL_checkudata(L, 1, META_MUSICDEF));
enum musicdef_e field = Lua_optoption(L, 2, -1, musicdef_fields_ref);
lua_settop(L, 2);
if (!musicdef)
return LUA_ErrInvalid(L, "musicdef_t");
switch (field)
{
case musicdef_name:
lua_pushstring(L, musicdef->name);
break;
case musicdef_title:
lua_pushstring(L, musicdef->title);
break;
case musicdef_alttitle:
lua_pushstring(L, musicdef->alttitle);
break;
case musicdef_authors:
lua_pushstring(L, musicdef->authors);
break;
default:
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
I_Assert(lua_istable(L, -1));
lua_pushlightuserdata(L, musicdef);
lua_rawget(L, -2);
if (!lua_istable(L, -1)) { // no extra values table
CONS_Debug(DBG_LUA, M_GetText("'%s' has no extvars table or field named '%s'; returning nil.\n"), "musicdef_t", lua_tostring(L, 2));
return 0;
}
lua_pushvalue(L, 2); // field name
lua_gettable(L, -2);
if (lua_isnil(L, -1)) // no value for this field
CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "musicdef_t", lua_tostring(L, 2));
break;
}
return 1;
}
static int lib_sMusicInfo(lua_State *L)
{
const char *music_name = lua_tolstring(L, 1, NULL);
LUA_PushUserdata(L, S_MusicInfo(music_name), META_MUSICDEF);
return 1;
}
// G_GAME
////////////
@ -4623,6 +4692,7 @@ static luaL_Reg lib[] = {
{"S_GetMusicLoopPoint",lib_sGetMusicLoopPoint},
{"S_PauseMusic",lib_sPauseMusic},
{"S_ResumeMusic", lib_sResumeMusic},
{"S_MusicInfo", lib_sMusicInfo},
// g_game
{"G_AddGametype", lib_gAddGametype},
@ -4661,6 +4731,11 @@ static luaL_Reg lib[] = {
int LUA_BaseLib(lua_State *L)
{
// musicdef_t
// Sound should have its whole own file for Lua, but this will do for now.
LUA_RegisterUserdataMetatable(L, META_MUSICDEF, musicdef_get, NULL, NULL);
musicdef_fields_ref = Lua_CreateFieldTable(L, musicdef_opt);
// Set metatable for string
lua_pushliteral(L, ""); // dummy string
lua_getmetatable(L, -1); // get string metatable

View file

@ -46,6 +46,8 @@ extern boolean ignoregameinputs;
#define META_SKINSPRITESLIST "SKIN_T*SKINSPRITES[]"
#define META_SKINSPRITESCOMPAT "SKIN_T*SPRITES" // TODO: 2.3: Delete
#define META_MUSICDEF "MUSICDEF_T*"
#define META_VERTEX "VERTEX_T*"
#define META_LINE "LINE_T*"
#define META_SIDE "SIDE_T*"

View file

@ -1801,6 +1801,27 @@ UINT32 S_GetMusicLength(void)
return I_GetSongLength();
}
//
// S_MusicInfo
//
// Returns metadata about supplied music
// If name is NULL, returns the currently playing music (if any)
//
musicdef_t *S_MusicInfo(const char *name)
{
if (!name)
name = music_name;
musicdef_t *def;
for (def = musicdefstart; def; def = def->next)
{
if (strcasecmp(def->name, name) == 0)
return def;
}
return NULL;
}
boolean S_SetMusicLoopPoint(UINT32 looppoint)
{
return I_SetSongLoopPoint(looppoint);

View file

@ -220,6 +220,9 @@ boolean S_PrepareSoundTest(void);
// Get Length of Music
UINT32 S_GetMusicLength(void);
// Get MUSICDEF of Music
musicdef_t *S_MusicInfo(const char *name);
// Set LoopPoint of Music
boolean S_SetMusicLoopPoint(UINT32 looppoint);