From d1534ebd1afb7dd061ed47ae9c349f318eab01d4 Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 22 Feb 2024 16:21:42 -0500 Subject: [PATCH 1/3] Add Lua bindings for MUSICDEF (read-only, of course) --- src/lua_baselib.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++ src/lua_libs.h | 2 + src/s_sound.c | 12 ++++++ src/s_sound.h | 3 ++ 4 files changed, 121 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 680c6a2c3..1ffcb0c11 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -172,6 +172,8 @@ static const struct { {META_SKINSPRITES, "skin_t.sprites"}, {META_SKINSPRITESLIST, "skin_t.sprites[]"}, + {META_MUSICDEF, "musicdef_t"}, + {META_VERTEX, "vertex_t"}, {META_LINE, "line_t"}, {META_SIDE, "side_t"}, @@ -3654,6 +3656,102 @@ static int lib_sResumeMusic(lua_State *L) return 1; } +enum musicdef_e +{ + musicdef_name, + musicdef_title, + musicdef_alttitle, + musicdef_authors, + musicdef_soundtestpage, + musicdef_soundtestcond, + musicdef_stoppingtics, + musicdef_bpm, + musicdef_loop_ms, + musicdef_allowed +}; + +static const char *const musicdef_opt[] = { + "name", + "title", + "alttitle", + "authors", + "soundtestpage", + "soundtestcond", + "stoppingtics", + "bpm", + "loop_ms", + "allowed", + 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; + case musicdef_soundtestpage: + lua_pushinteger(L, musicdef->soundtestpage); + break; + case musicdef_soundtestcond: + lua_pushinteger(L, musicdef->soundtestcond); + break; + case musicdef_stoppingtics: + lua_pushinteger(L, musicdef->stoppingtics); + break; + case musicdef_bpm: + lua_pushfixed(L, musicdef->bpm); + break; + case musicdef_loop_ms: + lua_pushinteger(L, musicdef->loop_ms); + break; + case musicdef_allowed: + lua_pushboolean(L, musicdef->allowed); + 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) +{ + LUA_PushUserdata(L, S_MusicInfo(), META_MUSICDEF); + return 1; +} + // G_GAME //////////// @@ -4531,6 +4629,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}, @@ -4569,6 +4668,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 a90d8ac7f..fab108592 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -45,6 +45,8 @@ extern boolean ignoregameinputs; #define META_SKINSPRITES "SKIN_T*SPRITES" #define META_SKINSPRITESLIST "SKIN_T*SPRITES[]" +#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 a579292ff..0654e705f 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1801,6 +1801,18 @@ UINT32 S_GetMusicLength(void) return I_GetSongLength(); } +musicdef_t *S_MusicInfo(void) +{ + musicdef_t *def; + for (def = musicdefstart; def; def = def->next) + { + if (strcasecmp(def->name, music_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 288859c8d..909a77e08 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(void); + // Set LoopPoint of Music boolean S_SetMusicLoopPoint(UINT32 looppoint); From d0689aab7abd822e271f4fa3284158d5061d4ae3 Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 22 Feb 2024 18:23:30 -0500 Subject: [PATCH 2/3] remove internal variables --- src/lua_baselib.c | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 1ffcb0c11..b191dba62 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3661,13 +3661,7 @@ enum musicdef_e musicdef_name, musicdef_title, musicdef_alttitle, - musicdef_authors, - musicdef_soundtestpage, - musicdef_soundtestcond, - musicdef_stoppingtics, - musicdef_bpm, - musicdef_loop_ms, - musicdef_allowed + musicdef_authors }; static const char *const musicdef_opt[] = { @@ -3675,12 +3669,6 @@ static const char *const musicdef_opt[] = { "title", "alttitle", "authors", - "soundtestpage", - "soundtestcond", - "stoppingtics", - "bpm", - "loop_ms", - "allowed", NULL, }; @@ -3709,24 +3697,6 @@ static int musicdef_get(lua_State *L) case musicdef_authors: lua_pushstring(L, musicdef->authors); break; - case musicdef_soundtestpage: - lua_pushinteger(L, musicdef->soundtestpage); - break; - case musicdef_soundtestcond: - lua_pushinteger(L, musicdef->soundtestcond); - break; - case musicdef_stoppingtics: - lua_pushinteger(L, musicdef->stoppingtics); - break; - case musicdef_bpm: - lua_pushfixed(L, musicdef->bpm); - break; - case musicdef_loop_ms: - lua_pushinteger(L, musicdef->loop_ms); - break; - case musicdef_allowed: - lua_pushboolean(L, musicdef->allowed); - break; default: lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); From b6faaf1e197e77572d11d91eea88cdcef5ad851c Mon Sep 17 00:00:00 2001 From: Arthur Date: Fri, 23 Feb 2024 10:02:41 -0500 Subject: [PATCH 3/3] Support passing name of music as a parameter --- src/lua_baselib.c | 3 ++- src/s_sound.c | 13 +++++++++++-- src/s_sound.h | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index b191dba62..1125ef7f8 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3718,7 +3718,8 @@ static int musicdef_get(lua_State *L) static int lib_sMusicInfo(lua_State *L) { - LUA_PushUserdata(L, S_MusicInfo(), META_MUSICDEF); + const char *music_name = lua_tolstring(L, 1, NULL); + LUA_PushUserdata(L, S_MusicInfo(music_name), META_MUSICDEF); return 1; } diff --git a/src/s_sound.c b/src/s_sound.c index 0654e705f..1a04e9ab8 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1801,12 +1801,21 @@ UINT32 S_GetMusicLength(void) return I_GetSongLength(); } -musicdef_t *S_MusicInfo(void) +// +// 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, music_name) == 0) + if (strcasecmp(def->name, name) == 0) return def; } diff --git a/src/s_sound.h b/src/s_sound.h index 909a77e08..98aebcc27 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -221,7 +221,7 @@ boolean S_PrepareSoundTest(void); UINT32 S_GetMusicLength(void); // Get MUSICDEF of Music -musicdef_t *S_MusicInfo(void); +musicdef_t *S_MusicInfo(const char *name); // Set LoopPoint of Music boolean S_SetMusicLoopPoint(UINT32 looppoint);