Compare commits

...
8 changed files with 259 additions and 72 deletions

No files matched your search

+31
View File
@@ -161,6 +161,37 @@ Duration is in milliseconds and is optional to set, default value is 84ms.
Exactly same as P_CheckSight but uses cheaper algorithm, useful for things like nametags. Doesn't work exactly
like P_CheckSight so don't use it for anything gameplay-related.
## musicdef_t
Userdata structure representing a musicdef. Fields:
`musicdef.name` - song identifier ("kmap01" for example).
`musicdef.usage`, `musicdef.source` - fields from vanilla MUSICDEFS lump.
`musicdef.filename` - unused for now.
`musicdef.title`, `musicdef.alttitle`, `musicdef.authors` - fields from MUSCINFO lump.
`#musicdef` - returns integer id for musicdef (which can be used as index in `musicdefs`).
All fields are read-only.
## S_FindMusicCredit(name)
Returns musicdef corresponding to music with given identifier. For example, `S_FindMusicCredit("kmap01")` will return
musicdef for green hills music.
## musicdefs
Global table for all musicdefs, similar to mobjinfo, states, etc. Can take either integer indices,
from `0` to `#musicdefs-1`, or string indices (which is equal to calling `S_FindMusicCredit`).
## addHook("MusicCredit", function(musicdef))
Hook is called whenever `S_ShowMusicCredit` (either from game or mod) is called. Takes musicdef as only argument, returning true
will overwrite vanilla behavior (not show music credit), can be used to implement custom music credit pop-ups.
# Other changes
## P_PlayRinglossSound(source, damager)
+2
View File
@@ -55,6 +55,7 @@
X (PlayerQuit),\
X (PlayerThink),/* P_PlayerThink */\
X (MusicChange),\
X (MusicCredit),\
X (ShouldSpin),/*SRB2KART*/\
X (ShouldExplode),/*SRB2KART*/\
X (ShouldSquish),/*SRB2KART*/\
@@ -130,6 +131,7 @@ int LUA_HookPlayerCanDamage(player_t *, mobj_t *);
void LUA_HookPlayerQuit(player_t *, int);
int LUA_HookPlayerCmd(player_t *, ticcmd_t *);
int LUA_HookMusicChange(const char *oldname, struct MusicChange *);
int LUA_HookMusicCredit(musicdef_t *musicdef);
int LUA_HookShouldSpin(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Should player be spun out?
int LUA_HookShouldExplode(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Should player be exploded?
+12
View File
@@ -1065,6 +1065,18 @@ int LUA_HookMusicChange(const char *oldname, struct MusicChange *param)
return hook.status;
}
int LUA_HookMusicCredit(musicdef_t *musicdef)
{
Hook_State hook;
if (prepare_hook(&hook, 0, HOOK(MusicCredit)))
{
LUA_PushUserdata(gL, musicdef, META_MUSICDEF);
call_hooks(&hook, 1, res_true);
}
return hook.status;
}
static int kartdamage_hook
(
player_t *player,
+130
View File
@@ -16,6 +16,7 @@
#include "dehacked.h"
#include "p_mobj.h"
#include "p_local.h"
#include "s_sound.h"
#include "z_zone.h"
#include "lua_script.h"
@@ -1072,6 +1073,109 @@ static int sfxinfo_num(lua_State *L)
return 1;
}
enum musicdef_e {
musicdef_name = 0,
musicdef_usage,
musicdef_source,
musicdef_filename,
musicdef_title,
musicdef_alttitle,
musicdef_authors,
};
const char *const musicdef_opt[] = {
"name",
"usage",
"source",
"filename",
"title",
"alttitle",
"authors",
NULL
};
static int musicdef_fields_ref = LUA_NOREF;
static int lib_sFindMusicCredit(lua_State *L)
{
const char *name = luaL_checkstring(L, 1);
LUA_PushUserdata(L, S_FindMusicCredit(name), META_MUSICDEF);
return 1;
}
static int lib_getMusicDef(lua_State *L)
{
musicdef_t *def = NULL;
if (lua_isnumber(L, 2))
def = S_GetMusicCredit(lua_tonumber(L, 2));
else if (lua_isstring(L, 2))
def = S_FindMusicCredit(lua_tostring(L, 2));
else
return luaL_error(L, "musicdefs index must be number or string (got %s)", luaL_typename(L, 2));
LUA_PushUserdata(L, def, META_MUSICDEF);
return 1;
}
static int lib_setMusicDef(lua_State *L)
{
return luaL_error(L, "musicdefs is read only");
}
static int lib_musicdefslen(lua_State *L)
{
lua_pushinteger(L, nummusicdefs);
return 1;
}
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);
I_Assert(musicdef != NULL);
switch (field)
{
case musicdef_name:
lua_pushstring(L, musicdef->name);
return 1;
case musicdef_usage:
lua_pushstring(L, musicdef->usage);
return 1;
case musicdef_source:
lua_pushstring(L, musicdef->source);
return 1;
case musicdef_filename:
lua_pushstring(L, musicdef->filename);
return 1;
case musicdef_title:
lua_pushstring(L, musicdef->title);
return 1;
case musicdef_alttitle:
lua_pushstring(L, musicdef->alttitle);
return 1;
case musicdef_authors:
lua_pushstring(L, musicdef->authors);
return 1;
default:
return luaL_error(L, LUA_QL("musicdef_t") " has no field named " LUA_QS, lua_tostring(L, 2));
}
return 0;
}
static int musicdef_num(lua_State *L)
{
musicdef_t *musicdef = *((musicdef_t **)luaL_checkudata(L, 1, META_MUSICDEF));
I_Assert(musicdef != NULL);
lua_pushinteger(L, musicdef->num);
return 1;
}
//////////////////////////////
//
// Now push all these functions into the Lua state!
@@ -1126,6 +1230,18 @@ int LUA_InfoLib(lua_State *L)
sfxinfo_fields_ref = Lua_CreateFieldTable(L, sfxinfo_opt);
luaL_newmetatable(L, META_MUSICDEF);
lua_pushcfunction(L, musicdef_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, musicdef_num);
lua_setfield(L, -2, "__len");
lua_pop(L, 1);
musicdef_fields_ref = Lua_CreateFieldTable(L, musicdef_opt);
lua_register(L, "S_FindMusicCredit", lib_sFindMusicCredit);
lua_newuserdata(L, 0);
lua_createtable(L, 0, 2);
lua_pushcfunction(L, lib_getSprname);
@@ -1176,5 +1292,19 @@ int LUA_InfoLib(lua_State *L)
lua_pushvalue(L, -1);
lua_setglobal(L, "S_sfx");
lua_setglobal(L, "sfxinfo");
lua_newuserdata(L, 0);
lua_createtable(L, 0, 2);
lua_pushcfunction(L, lib_getMusicDef);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, lib_setMusicDef);
lua_setfield(L, -2, "__newindex");
lua_pushcfunction(L, lib_musicdefslen);
lua_setfield(L, -2, "__len");
lua_setmetatable(L, -2);
lua_setglobal(L, "musicdefs");
return 0;
}
+5 -1
View File
@@ -10,6 +10,9 @@
/// \file lua_libs.h
/// \brief libraries for Lua scripting
#include "doomtype.h"
#include "blua/lua.h"
extern lua_State *gL;
#define LREG_VALID "VALID_USERDATA"
@@ -20,6 +23,7 @@ extern lua_State *gL;
#define META_STATE "STATE_T*"
#define META_MOBJINFO "MOBJINFO_T*"
#define META_SFXINFO "SFXINFO_T*"
#define META_MUSICDEF "MUSICDEF_T*"
#define META_MOBJ "MOBJ_T*"
#define META_MAPTHING "MAPTHING_T*"
@@ -68,4 +72,4 @@ int LUA_SkinLib(lua_State *L);
int LUA_ThinkerLib(lua_State *L);
int LUA_MapLib(lua_State *L);
int LUA_BlockmapLib(lua_State *L);
int LUA_HudLib(lua_State *L);
int LUA_HudLib(lua_State *L);
+18 -20
View File
@@ -8458,7 +8458,7 @@ static void M_MusicTest(INT32 choice)
{
(void)choice;
if (!S_PrepareSoundTest())
if (!nummusicdefs)
{
M_StartMessage(M_GetText("No selectable tracks found.\n"),NULL,MM_NOTHING);
return;
@@ -8537,33 +8537,33 @@ static void M_DrawMusicTest(void)
{
INT32 t, b, q, m = 128;
if (numsoundtestdefs <= 8)
if (nummusicdefs <= 8)
{
t = 0;
b = numsoundtestdefs - 1;
b = nummusicdefs - 1;
i = 0;
}
else
{
q = m;
m = (5*m)/numsoundtestdefs;
m = (5*m)/nummusicdefs;
if (st_sel < 3)
{
t = 0;
b = 7;
i = 0;
}
else if (st_sel >= numsoundtestdefs-4)
else if (st_sel >= nummusicdefs-4)
{
t = numsoundtestdefs - 8;
b = numsoundtestdefs - 1;
t = nummusicdefs - 8;
b = nummusicdefs - 1;
i = q-m;
}
else
{
t = st_sel - 3;
b = st_sel + 4;
i = (t * (q-m))/(numsoundtestdefs - 8);
i = (t * (q-m))/(nummusicdefs - 8);
}
}
@@ -8572,7 +8572,7 @@ static void M_DrawMusicTest(void)
if (t != 0)
V_DrawString(20+280+4, 60+4 - (skullAnimCounter/5), V_YELLOWMAP, "\x1A");
if (b != numsoundtestdefs - 1)
if (b != nummusicdefs - 1)
V_DrawString(20+280+4, 60+128-12 + (skullAnimCounter/5), V_YELLOWMAP, "\x1B");
x = 24;
@@ -8586,8 +8586,9 @@ static void M_DrawMusicTest(void)
V_DrawFill(20, y-4, 280-1, 16, 237);
{
const musicdef_t *def = S_GetMusicCredit(t);
const size_t MAXLENGTH = 34;
const char *songname = soundtestdefs[t]->title[0] ? soundtestdefs[t]->title : soundtestdefs[t]->source;
const char *songname = def->title[0] ? def->title : def->source;
size_t namelength = strlen(songname);
@@ -8600,7 +8601,7 @@ static void M_DrawMusicTest(void)
buf[MAXLENGTH] = 0;
V_DrawString(x, y, (t == st_sel ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE|V_MONOSPACE, buf);
if (curplaying == soundtestdefs[t])
if (curplaying == def)
{
V_DrawFill(20+280-9, y-4, 8, 16, 230);
}
@@ -8618,7 +8619,7 @@ static void M_HandleMusicTest(INT32 choice)
switch (choice)
{
case KEY_DOWNARROW:
if (st_sel++ >= numsoundtestdefs-1)
if (st_sel++ >= nummusicdefs-1)
st_sel = 0;
{
S_StartSound(NULL, sfx_menu1);
@@ -8627,18 +8628,18 @@ static void M_HandleMusicTest(INT32 choice)
break;
case KEY_UPARROW:
if (!st_sel--)
st_sel = numsoundtestdefs-1;
st_sel = nummusicdefs-1;
{
S_StartSound(NULL, sfx_menu1);
}
st_musictime = 0;
break;
case KEY_PGDN:
if (st_sel < numsoundtestdefs-1)
if (st_sel < nummusicdefs-1)
{
st_sel += 3;
if (st_sel >= numsoundtestdefs-1)
st_sel = numsoundtestdefs-1;
if (st_sel >= nummusicdefs-1)
st_sel = nummusicdefs-1;
S_StartSound(NULL, sfx_menu1);
}
st_musictime = 0;
@@ -8672,7 +8673,7 @@ static void M_HandleMusicTest(INT32 choice)
case KEY_ENTER:
S_StopSounds();
S_StopMusic();
curplaying = soundtestdefs[st_sel];
curplaying = S_GetMusicCredit(st_sel);
S_ChangeMusicInternal(curplaying->name, true);
break;
@@ -8681,9 +8682,6 @@ static void M_HandleMusicTest(INT32 choice)
}
if (exitmenu)
{
Z_Free(soundtestdefs);
soundtestdefs = NULL;
if (currentMenu->prevMenu)
M_SetupNextMenu(currentMenu->prevMenu);
else
+58 -43
View File
@@ -32,6 +32,7 @@
#include "m_menu.h" // bird music stuff
#include "lua_hook.h" // MusicChange hook
#include "lua_hud.h" // LUA_HudEnabled(hud_musiccredit)
static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo);
static void SetChannelsNum(void);
@@ -1202,8 +1203,58 @@ static consvar_t *music_refade_cv;
/// Music Definitions
/// ------------------------
musicdef_t *musicdefstart = NULL; // First music definition
struct cursongcredit cursongcredit; // Currently displayed song credit info
// Similar system to vissprite allocation. Exists so external pointers to musicdefs are not invalidated
// when allocating more space for musicdefs
#define MUSICDEFCHUNKBITS 6
#define MUSICDEFSPERCHUNK (1 << MUSICDEFCHUNKBITS)
#define MUSICDEFINDEXMASK (MUSICDEFSPERCHUNK - 1)
static musicdef_t **musicdefs = NULL;
static INT32 numchunks = 0;
INT32 nummusicdefs = 0;
//
// S_GetMusicCredit
//
// Return music credit with given index.
//
musicdef_t *S_GetMusicCredit(INT32 i)
{
if (i < 0 || i >= nummusicdefs)
return NULL;
INT32 chunk = i >> MUSICDEFCHUNKBITS;
i &= MUSICDEFINDEXMASK;
return &musicdefs[chunk][i];
}
//
// S_AddMusicCredit
//
// Return new music credit, allocates memory for it if needed.
//
static musicdef_t *S_AddMusicCredit(void)
{
INT32 chunk = nummusicdefs >> MUSICDEFCHUNKBITS;
INT32 i = nummusicdefs & MUSICDEFINDEXMASK;
// Allocate new chunk if needed. Other chunks stay valid
if (chunk == numchunks)
{
++numchunks;
musicdefs = (musicdef_t**)Z_Realloc(musicdefs, sizeof(musicdef_t*)*numchunks, PU_STATIC, NULL);
musicdefs[chunk] = Z_Calloc(sizeof(musicdef_t)*MUSICDEFSPERCHUNK, PU_STATIC, NULL);
}
// Store "id" of new musicdef (mostly exists only for lua)
musicdefs[chunk][i].num = nummusicdefs;
++nummusicdefs;
return &musicdefs[chunk][i];
}
struct cursongcredit cursongcredit = {0}; // Currently displayed song credit info
static boolean
ReadMusicDefFields (UINT16 wadnum, int line, char *stoken, musicdef_t **defp)
@@ -1231,14 +1282,11 @@ ReadMusicDefFields (UINT16 wadnum, int line, char *stoken, musicdef_t **defp)
// Nothing found, add to the end.
if (!def)
{
def = Z_Calloc(sizeof (musicdef_t), PU_STATIC, NULL);
def = S_AddMusicCredit();
STRBUFCPY(def->name, value);
strlwr(def->name);
def->hash = quickncasehash (def->name, 6);
def->next = musicdefstart;
musicdefstart = def;
}
(*defp) = def;
@@ -1423,8 +1471,10 @@ musicdef_t *S_FindMusicCredit(const char *musname)
UINT32 hash = quickncasehash (musname, 6);
musicdef_t *def;
for (def = musicdefstart; def; def = def->next)
for (INT32 i = 0; i < nummusicdefs; ++i)
{
def = S_GetMusicCredit(i);
if (hash != def->hash)
continue;
if (stricmp(def->name, musname))
@@ -1452,7 +1502,7 @@ void S_ShowSpecifiedMusicCredit(const char *musname)
def = S_FindMusicCredit(musname);
if (def)
if (def && !LUA_HookMusicCredit(def))
{
cursongcredit.def = def;
cursongcredit.anim = 5*TICRATE;
@@ -1471,41 +1521,6 @@ void S_ShowMusicCredit(void)
S_ShowSpecifiedMusicCredit(music.name);
}
musicdef_t **soundtestdefs = NULL;
INT32 numsoundtestdefs = 0;
//
// S_PrepareSoundTest
//
// Prepare sound test. What am I, your butler?
//
boolean S_PrepareSoundTest(void)
{
musicdef_t *def;
INT32 pos = numsoundtestdefs = 0;
for (def = musicdefstart; def; def = def->next)
{
numsoundtestdefs++;
}
if (!numsoundtestdefs)
return false;
if (soundtestdefs)
Z_Free(soundtestdefs);
if (!(soundtestdefs = Z_Malloc(numsoundtestdefs*sizeof(musicdef_t *), PU_STATIC, NULL)))
I_Error("S_PrepareSoundTest(): could not allocate soundtestdefs.");
for (def = musicdefstart; def /*&& i < numsoundtestdefs*/; def = def->next)
{
soundtestdefs[pos++] = def;
}
return true;
}
/// ------------------------
/// Music Status
/// ------------------------
+3 -8
View File
@@ -182,14 +182,9 @@ typedef struct musicdef_s
char alttitle[256];
char authors[256];
boolean use_info;
struct musicdef_s *next;
size_t num;
} musicdef_t;
extern musicdef_t *musicdefstart;
extern musicdef_t **soundtestdefs;
extern INT32 numsoundtestdefs;
extern UINT8 soundtestpage;
extern struct cursongcredit
{
musicdef_t *def;
@@ -198,17 +193,17 @@ extern struct cursongcredit
UINT8 trans;
} cursongcredit;
extern INT32 nummusicdefs;
void S_LoadMusicDefs(UINT16 wadnum);
void S_InitMusicDefs(void);
void S_LoadMTDefs(UINT16 wadnum);
void S_InitMTDefs(void);
musicdef_t *S_GetMusicCredit(INT32 i);
musicdef_t *S_FindMusicCredit(const char *musname);
void S_ShowSpecifiedMusicCredit(const char *musname);
void S_ShowMusicCredit(void);
boolean S_PrepareSoundTest(void);
//
// Music Seeking
//