diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 1ffa3968b..e30c84bc3 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -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 diff --git a/src/lua_libs.h b/src/lua_libs.h index e1585f488..2961abf9d 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -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*" diff --git a/src/s_sound.c b/src/s_sound.c index 0329c289e..2ded96240 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -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); diff --git a/src/s_sound.h b/src/s_sound.h index 589060c8c..46af5d1b7 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -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);