Merge branch 'lua-music' into 'next'

Expose more music-related functions to Lua

See merge request STJr/SRB2!817
This commit is contained in:
LJ Sonic 2020-03-19 06:53:57 -04:00
commit 92016a742b
6 changed files with 157 additions and 29 deletions

View File

@ -1040,11 +1040,60 @@ static int lib_pSetObjectMomZ(lua_State *L)
return 0;
}
static int lib_pPlayJingle(lua_State *L)
{
player_t *player = NULL;
jingletype_t jingletype = luaL_checkinteger(L, 2);
//NOHUD
//INLEVEL
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 (jingletype >= NUMJINGLES)
return luaL_error(L, "jingletype %d out of range (0 - %d)", jingletype, NUMJINGLES-1);
P_PlayJingle(player, jingletype);
return 0;
}
static int lib_pPlayJingleMusic(lua_State *L)
{
player_t *player = NULL;
const char *musnamearg = luaL_checkstring(L, 2);
char musname[7], *p = musname;
UINT16 musflags = luaL_optinteger(L, 3, 0);
boolean looping = lua_opttrueboolean(L, 4);
jingletype_t jingletype = luaL_optinteger(L, 5, JT_OTHER);
//NOHUD
//INLEVEL
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 (jingletype >= NUMJINGLES)
return luaL_error(L, "jingletype %d out of range (0 - %d)", jingletype, NUMJINGLES-1);
musname[6] = '\0';
strncpy(musname, musnamearg, 6);
while (*p) {
*p = tolower(*p);
++p;
}
P_PlayJingleMusic(player, musname, musflags, looping, jingletype);
return 0;
}
static int lib_pRestoreMusic(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
INLEVEL
//NOHUD
//INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
if (P_IsLocalPlayer(player))
@ -1674,11 +1723,15 @@ static int lib_pPlayVictorySound(lua_State *L)
static int lib_pPlayLivesJingle(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
player_t *player = NULL;
//NOHUD
//INLEVEL
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");
}
P_PlayLivesJingle(player);
return 0;
}
@ -2342,7 +2395,7 @@ static int lib_sStartSound(lua_State *L)
const void *origin = NULL;
sfxenum_t sound_id = luaL_checkinteger(L, 2);
player_t *player = NULL;
//NOHUD // kys @whoever did this.
//NOHUD
if (sound_id >= NUMSFX)
return luaL_error(L, "sfx %d out of range (0 - %d)", sound_id, NUMSFX-1);
if (!lua_isnil(L, 1))
@ -2373,7 +2426,7 @@ static int lib_sStartSoundAtVolume(lua_State *L)
sfxenum_t sound_id = luaL_checkinteger(L, 2);
INT32 volume = (INT32)luaL_checkinteger(L, 3);
player_t *player = NULL;
NOHUD
//NOHUD
if (!lua_isnil(L, 1))
{
@ -2397,7 +2450,7 @@ static int lib_sStartSoundAtVolume(lua_State *L)
static int lib_sStopSound(lua_State *L)
{
void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
NOHUD
//NOHUD
if (!origin)
return LUA_ErrInvalid(L, "mobj_t");
S_StopSound(origin);
@ -2414,7 +2467,7 @@ static int lib_sChangeMusic(lua_State *L)
boolean looping;
player_t *player = NULL;
UINT16 music_flags = 0;
NOHUD
//NOHUD
if (lua_isnumber(L, 1))
{
@ -2443,7 +2496,7 @@ static int lib_sChangeMusic(lua_State *L)
boolean looping = (boolean)lua_opttrueboolean(L, 2);
player_t *player = NULL;
UINT16 music_flags = 0;
NOHUD
//NOHUD
#endif
if (!lua_isnone(L, 3) && lua_isuserdata(L, 3))
@ -2474,7 +2527,7 @@ static int lib_sSpeedMusic(lua_State *L)
fixed_t fixedspeed = luaL_checkfixed(L, 1);
float speed = FIXED_TO_FLOAT(fixedspeed);
player_t *player = NULL;
NOHUD
//NOHUD
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
{
player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
@ -2489,7 +2542,7 @@ static int lib_sSpeedMusic(lua_State *L)
static int lib_sStopMusic(lua_State *L)
{
player_t *player = NULL;
NOHUD
//NOHUD
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -2505,7 +2558,7 @@ static int lib_sSetInternalMusicVolume(lua_State *L)
{
UINT32 volume = (UINT32)luaL_checkinteger(L, 1);
player_t *player = NULL;
NOHUD
//NOHUD
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
{
player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
@ -2525,7 +2578,7 @@ static int lib_sSetInternalMusicVolume(lua_State *L)
static int lib_sStopFadingMusic(lua_State *L)
{
player_t *player = NULL;
NOHUD
//NOHUD
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -2548,7 +2601,7 @@ static int lib_sFadeMusic(lua_State *L)
UINT32 ms;
INT32 source_volume;
player_t *player = NULL;
NOHUD
//NOHUD
if (!lua_isnone(L, 3) && lua_isuserdata(L, 3))
{
player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER));
@ -2576,8 +2629,6 @@ static int lib_sFadeMusic(lua_State *L)
ms = (UINT32)luaL_checkinteger(L, 3);
}
NOHUD
if (!player || P_IsLocalPlayer(player))
lua_pushboolean(L, S_FadeMusicFromVolume(target_volume, source_volume, ms));
else
@ -2589,7 +2640,7 @@ static int lib_sFadeOutStopMusic(lua_State *L)
{
UINT32 ms = (UINT32)luaL_checkinteger(L, 1);
player_t *player = NULL;
NOHUD
//NOHUD
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
{
player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
@ -2605,10 +2656,29 @@ static int lib_sFadeOutStopMusic(lua_State *L)
return 1;
}
static int lib_sGetMusicLength(lua_State *L)
{
lua_pushinteger(L, S_GetMusicLength());
return 1;
}
static int lib_sGetMusicPosition(lua_State *L)
{
lua_pushinteger(L, S_GetMusicPosition());
return 1;
}
static int lib_sSetMusicPosition(lua_State *L)
{
UINT32 pos = (UINT32)luaL_checkinteger(L, 1);
lua_pushboolean(L, S_SetMusicPosition(pos));
return 1;
}
static int lib_sOriginPlaying(lua_State *L)
{
void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
NOHUD
//NOHUD
INLEVEL
if (!origin)
return LUA_ErrInvalid(L, "mobj_t");
@ -2619,7 +2689,7 @@ static int lib_sOriginPlaying(lua_State *L)
static int lib_sIdPlaying(lua_State *L)
{
sfxenum_t id = luaL_checkinteger(L, 1);
NOHUD
//NOHUD
if (id >= NUMSFX)
return luaL_error(L, "sfx %d out of range (0 - %d)", id, NUMSFX-1);
lua_pushboolean(L, S_IdPlaying(id));
@ -2630,7 +2700,7 @@ static int lib_sSoundPlaying(lua_State *L)
{
void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
sfxenum_t id = luaL_checkinteger(L, 2);
NOHUD
//NOHUD
INLEVEL
if (!origin)
return LUA_ErrInvalid(L, "mobj_t");
@ -2648,7 +2718,7 @@ static int lib_sStartMusicCaption(lua_State *L)
const char *caption = luaL_checkstring(L, 1);
UINT16 lifespan = (UINT16)luaL_checkinteger(L, 2);
//HUDSAFE
INLEVEL
//INLEVEL
if (!lua_isnone(L, 3) && lua_isuserdata(L, 3))
{
@ -3069,6 +3139,8 @@ static luaL_Reg lib[] = {
{"P_InSpaceSector",lib_pInSpaceSector},
{"P_InQuicksand",lib_pInQuicksand},
{"P_SetObjectMomZ",lib_pSetObjectMomZ},
{"P_PlayJingle",lib_pPlayJingle},
{"P_PlayJingleMusic",lib_pPlayJingleMusic},
{"P_RestoreMusic",lib_pRestoreMusic},
{"P_SpawnShieldOrb",lib_pSpawnShieldOrb},
{"P_SpawnGhostMobj",lib_pSpawnGhostMobj},
@ -3189,6 +3261,9 @@ static luaL_Reg lib[] = {
{"S_StopFadingMusic",lib_sStopFadingMusic},
{"S_FadeMusic",lib_sFadeMusic},
{"S_FadeOutStopMusic",lib_sFadeOutStopMusic},
{"S_GetMusicLength",lib_sGetMusicLength},
{"S_GetMusicPosition",lib_sGetMusicPosition},
{"S_SetMusicPosition",lib_sSetMusicPosition},
{"S_OriginPlaying",lib_sOriginPlaying},
{"S_IdPlaying",lib_sIdPlaying},
{"S_SoundPlaying",lib_sSoundPlaying},

View File

@ -58,6 +58,7 @@ enum hook {
hook_ViewpointSwitch,
hook_SeenPlayer,
hook_PlayerThink,
hook_ShouldJingleContinue,
hook_MAX // last hook
};
@ -110,5 +111,6 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean
boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_NAMECHECK
#endif
#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink
boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname); // Hook for whether a jingle of the given music should continue playing
#endif

View File

@ -69,6 +69,7 @@ const char *const hookNames[hook_MAX+1] = {
"ViewpointSwitch",
"SeenPlayer",
"PlayerThink",
"ShouldJingleContinue",
NULL
};
@ -81,6 +82,7 @@ struct hook_s
union {
mobjtype_t mt;
char *skinname;
char *musname;
char *funcname;
} s;
boolean error;
@ -149,6 +151,7 @@ static int lib_addHook(lua_State *L)
luaL_argcheck(L, hook.s.mt < NUMMOBJTYPES, 2, "invalid mobjtype_t");
break;
case hook_BotAI:
case hook_ShouldJingleContinue:
hook.s.skinname = NULL;
if (lua_isstring(L, 2))
{ // lowercase copy
@ -1660,4 +1663,47 @@ boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend)
}
#endif // SEENAMES
boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname)
{
hook_p hookp;
boolean keepplaying = false;
if (!gL || !(hooksAvailable[hook_ShouldJingleContinue/8] & (1<<(hook_ShouldJingleContinue%8))))
return true;
lua_settop(gL, 0);
hud_running = true; // local hook
for (hookp = roothook; hookp; hookp = hookp->next)
{
if (hookp->type != hook_ShouldJingleContinue
|| (hookp->s.musname && strcmp(hookp->s.musname, musname)))
continue;
if (lua_gettop(gL) == 0)
{
LUA_PushUserdata(gL, player, META_PLAYER);
lua_pushstring(gL, musname);
}
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushvalue(gL, -3);
lua_pushvalue(gL, -3);
if (lua_pcall(gL, 2, 1, 0)) {
if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
hookp->error = true;
continue;
}
if (!lua_isnil(gL, -1) && lua_toboolean(gL, -1))
keepplaying = true; // Keep playing this boolean
lua_pop(gL, 1);
}
lua_settop(gL, 0);
hud_running = false;
return keepplaying;
}
#endif

View File

@ -250,7 +250,7 @@ extern jingle_t jingleinfo[NUMJINGLES];
#define JINGLEPOSTFADE 1000
void P_PlayJingle(player_t *player, jingletype_t jingletype);
boolean P_EvaluateMusicStatus(UINT16 status);
boolean P_EvaluateMusicStatus(UINT16 status, const char *musname);
void P_PlayJingleMusic(player_t *player, const char *musname, UINT16 musflags, boolean looping, UINT16 status);
//

View File

@ -1536,7 +1536,7 @@ void P_PlayJingle(player_t *player, jingletype_t jingletype)
void P_PlayJingleMusic(player_t *player, const char *musname, UINT16 musflags, boolean looping, UINT16 status)
{
// If gamestate != GS_LEVEL, always play the jingle (1-up intermission)
if (gamestate == GS_LEVEL && !P_IsLocalPlayer(player))
if (gamestate == GS_LEVEL && player && !P_IsLocalPlayer(player))
return;
S_RetainMusic(musname, musflags, looping, 0, status);
@ -1544,7 +1544,7 @@ void P_PlayJingleMusic(player_t *player, const char *musname, UINT16 musflags, b
S_ChangeMusicInternal(musname, looping);
}
boolean P_EvaluateMusicStatus(UINT16 status)
boolean P_EvaluateMusicStatus(UINT16 status, const char *musname)
{
// \todo lua hook
int i;
@ -1601,8 +1601,13 @@ boolean P_EvaluateMusicStatus(UINT16 status)
result = (players[i].nightstime && players[i].nightstime <= 10*TICRATE);
break;
case JT_NONE: // Null state
case JT_OTHER: // Other state
#ifdef HAVE_BLUA
result = LUAh_ShouldJingleContinue(&players[i], musname);
break;
#endif
case JT_NONE: // Null state
case JT_MASTER: // Main level music
default:
result = true;

View File

@ -2045,7 +2045,7 @@ static musicstack_t *S_GetMusicStackEntry(UINT16 status, boolean fromfirst, INT1
if (!status || mst->status == status)
{
if (P_EvaluateMusicStatus(mst->status))
if (P_EvaluateMusicStatus(mst->status, mst->musname))
{
if (!S_MusicExists(mst->musname, !midi_disabled, !digital_disabled)) // paranoia
S_RemoveMusicStackEntry(mst); // then continue