From ac7781a3b3ac1b96132b5c5ef44652f00330b604 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sat, 31 Oct 2020 20:15:41 -0500 Subject: [PATCH] Expose more music functions to Lua --- src/dehacked.c | 16 ++++ src/lua_baselib.c | 188 ++++++++++++++++++++++++++++++++++++++++++++++ src/lua_hook.h | 2 + src/lua_hooklib.c | 60 +++++++++++++++ src/s_sound.c | 7 +- 5 files changed, 267 insertions(+), 6 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index ca013a25d..ae22e19d5 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -26,6 +26,7 @@ #include "dehacked.h" #include "st_stuff.h" #include "i_system.h" +#include "i_sound.h" // musictype_t (for lua) #include "p_local.h" // for var1 and var2, and some constants #include "p_setup.h" #include "r_data.h" @@ -10106,6 +10107,21 @@ struct { {"MA_NOCUTSCENES",MA_NOCUTSCENES}, {"MA_INGAME",MA_INGAME}, + // music types + {"MU_NONE", MU_NONE}, + {"MU_CMD", MU_CMD}, + {"MU_WAV", MU_WAV}, + {"MU_MOD", MU_MOD}, + {"MU_MID", MU_MID}, + {"MU_OGG", MU_OGG}, + {"MU_MP3", MU_MP3}, + {"MU_MP3_MAD_UNUSED", MU_MP3_MAD_UNUSED}, + {"MU_FLAC", MU_FLAC}, + {"MU_MODPLUG_UNUSED", MU_MODPLUG_UNUSED}, + {"MU_GME", MU_GME}, + {"MU_MOD_EX", MU_MOD_EX}, + {"MU_MID_EX", MU_MID_EX}, + {NULL,0} }; diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 132ebc1a8..6cb3a0719 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3006,6 +3006,185 @@ static int lib_sStartMusicCaption(lua_State *L) return 0; } +static int lib_sMusicType(lua_State *L) +{ + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) + { + player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + lua_pushinteger(L, S_MusicType()); + else + lua_pushnil(L); + return 1; +} + +static int lib_sMusicPlaying(lua_State *L) +{ + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) + { + player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + lua_pushboolean(L, S_MusicPlaying()); + else + lua_pushnil(L); + return 1; +} + +static int lib_sMusicPaused(lua_State *L) +{ + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) + { + player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + lua_pushboolean(L, S_MusicPaused()); + else + lua_pushnil(L); + return 1; +} + +static int lib_sMusicName(lua_State *L) +{ + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) + { + player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + lua_pushstring(L, S_MusicName()); + else + lua_pushnil(L); + return 1; +} + +static int lib_sMusicExists(lua_State *L) +{ + boolean checkMIDI = lua_opttrueboolean(L, 2); + boolean checkDigi = lua_opttrueboolean(L, 3); +#ifdef MUSICSLOT_COMPATIBILITY + const char *music_name; + UINT32 music_num; + char music_compat_name[7]; + UINT16 music_flags = 0; + NOHUD + if (lua_isnumber(L, 1)) + { + music_num = (UINT32)luaL_checkinteger(L, 1); + music_flags = (UINT16)(music_num & 0x0000FFFF); + if (music_flags && music_flags <= 1035) + snprintf(music_compat_name, 7, "%sM", G_BuildMapName((INT32)music_flags)); + else if (music_flags && music_flags <= 1050) + strncpy(music_compat_name, compat_special_music_slots[music_flags - 1036], 7); + else + music_compat_name[0] = 0; // becomes empty string + music_compat_name[6] = 0; + music_name = (const char *)&music_compat_name; + } + else + { + music_num = 0; + music_name = luaL_checkstring(L, 1); + } +#else + const char *music_name = luaL_checkstring(L, 1); +#endif + NOHUD + lua_pushboolean(L, S_MusicExists(music_name, checkMIDI, checkDigi)); + return 1; +} + +static int lib_sSetMusicLoopPoint(lua_State *L) +{ + UINT32 looppoint = (UINT32)luaL_checkinteger(L, 1); + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) + { + player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + lua_pushboolean(L, S_SetMusicLoopPoint(looppoint)); + else + lua_pushnil(L); + return 1; +} + +static int lib_sGetMusicLoopPoint(lua_State *L) +{ + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) + { + player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + lua_pushinteger(L, (int)S_GetMusicLoopPoint()); + else + lua_pushnil(L); + return 1; +} + +static int lib_sPauseMusic(lua_State *L) +{ + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) + { + player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + { + S_PauseAudio(); + lua_pushboolean(L, true); + } + else + lua_pushnil(L); + return 1; +} + +static int lib_sResumeMusic(lua_State *L) +{ + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) + { + player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + { + S_ResumeAudio(); + lua_pushboolean(L, true); + } + else + lua_pushnil(L); + return 1; +} + // G_GAME //////////// @@ -3712,6 +3891,15 @@ static luaL_Reg lib[] = { {"S_IdPlaying",lib_sIdPlaying}, {"S_SoundPlaying",lib_sSoundPlaying}, {"S_StartMusicCaption", lib_sStartMusicCaption}, + {"S_MusicType",lib_sMusicType}, + {"S_MusicPlaying",lib_sMusicPlaying}, + {"S_MusicPaused",lib_sMusicPaused}, + {"S_MusicName",lib_sMusicName}, + {"S_MusicExists",lib_sMusicExists}, + {"S_SetMusicLoopPoint",lib_sSetMusicLoopPoint}, + {"S_GetMusicLoopPoint",lib_sGetMusicLoopPoint}, + {"S_PauseMusic",lib_sPauseMusic}, + {"S_ResumeMusic", lib_sResumeMusic}, // g_game {"G_AddGametype", lib_gAddGametype}, diff --git a/src/lua_hook.h b/src/lua_hook.h index 47850812f..796f3a9d2 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -60,6 +60,7 @@ enum hook { hook_ShouldJingleContinue, hook_GameQuit, hook_PlayerCmd, + hook_MusicChange, hook_MAX // last hook }; @@ -118,3 +119,4 @@ boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_ boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname); // Hook for whether a jingle of the given music should continue playing void LUAh_GameQuit(void); // Hook for game quitting boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Hook for building player's ticcmd struct (Ported from SRB2Kart) +boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping, UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms); // Hook for music changes \ No newline at end of file diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 65d483dc1..117aa48a3 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -76,6 +76,7 @@ const char *const hookNames[hook_MAX+1] = { "ShouldJingleContinue", "GameQuit", "PlayerCmd", + "MusicChange", NULL }; @@ -1912,3 +1913,62 @@ boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd) hook_cmd_running = false; return hooked; } + +// Hook for music changes +boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping, + UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms) +{ + hook_p hookp; + boolean hooked = false; + + if (!gL || !(hooksAvailable[hook_MusicChange/8] & (1<<(hook_MusicChange%8)))) + return false; + + lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); + + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == hook_MusicChange) + { + PushHook(gL, hookp); + lua_pushstring(gL, oldname); + lua_pushstring(gL, newname); + lua_pushinteger(gL, *mflags); + lua_pushboolean(gL, *looping); + lua_pushinteger(gL, *position); + lua_pushinteger(gL, *prefadems); + lua_pushinteger(gL, *fadeinms); + if (lua_pcall(gL, 7, 6, 1)) { + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); + lua_pop(gL, 1); + continue; + } + + // output 1: true, false, or string musicname override + if (lua_isboolean(gL, -6) && lua_toboolean(gL, -6)) + hooked = true; + else if (lua_isstring(gL, -6)) + strncpy(newname, lua_tostring(gL, -6), 7); + // output 2: mflags override + if (lua_isnumber(gL, -5)) + *mflags = lua_tonumber(gL, -5); + // output 3: looping override + if (lua_isboolean(gL, -4)) + *looping = lua_toboolean(gL, -4); + // output 4: position override + if (lua_isboolean(gL, -3)) + *position = lua_tonumber(gL, -3); + // output 5: prefadems override + if (lua_isboolean(gL, -2)) + *prefadems = lua_tonumber(gL, -2); + // output 6: fadeinms override + if (lua_isboolean(gL, -1)) + *fadeinms = lua_tonumber(gL, -1); + + lua_pop(gL, 7); // Pop returned values and error handler + } + + lua_settop(gL, 0); + newname[6] = 0; + return hooked; +} \ No newline at end of file diff --git a/src/s_sound.c b/src/s_sound.c index 793794aa7..36bd454c1 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -29,10 +29,7 @@ #include "fastcmp.h" #include "m_misc.h" // for tunes command #include "m_cond.h" // for conditionsets - -#ifdef HAVE_LUA_MUSICPLUS #include "lua_hook.h" // MusicChange hook -#endif #ifdef HW3SOUND // 3D Sound Interface @@ -2272,10 +2269,8 @@ void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32 return; strncpy(newmusic, mmusic, 7); -#ifdef HAVE_LUA_MUSICPLUS - if(LUAh_MusicChange(music_name, newmusic, &mflags, &looping, &position, &prefadems, &fadeinms)) + if (LUAh_MusicChange(music_name, newmusic, &mflags, &looping, &position, &prefadems, &fadeinms)) return; -#endif newmusic[6] = 0; // No Music (empty string)