From 3b48ca6c9c50c5ff47736bbc259db2126d1a954d Mon Sep 17 00:00:00 2001 From: NepDisk Date: Thu, 30 Apr 2026 16:56:22 -0400 Subject: [PATCH] Encoremusic mapheader option --- src/deh_soc.c | 24 ++++++++++++++++++++++++ src/doomstat.h | 2 ++ src/lua_maplib.c | 17 +++++++++++++++++ src/p_setup.c | 11 ++++++++--- src/s_sound.c | 18 +++++++++++------- 5 files changed, 62 insertions(+), 10 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index b158930cb..6d5926c47 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -1263,6 +1263,30 @@ void readlevelheader(MYFILE *f, char * name) mapheaderinfo[num]->musname_size = j; } } + else if (fastcmp(word, "ENCOREMUSIC")) + { + if (fastcmp(word2, "NONE")) + { + mapheaderinfo[num]->encoremusname[0][0] = 0; // becomes empty string + mapheaderinfo[num]->encoremusname_size = 0; + } + else + { + UINT8 j = 0; // i was declared elsewhere + tmp = strtok(word2, ","); + do { + if (j >= MAXMUSNAMES) + break; + deh_strlcpy(mapheaderinfo[num]->encoremusname[j], tmp, + sizeof(mapheaderinfo[num]->encoremusname[j]), va("Level header %d: encore music", num)); + j++; + } while ((tmp = strtok(NULL,",")) != NULL); + + if (tmp != NULL) + deh_warning("Level header %d: additional music slots past %d discarded", num, MAXMUSNAMES); + mapheaderinfo[num]->encoremusname_size = j; + } + } else if (fastcmp(word, "MUSICSLOT")) deh_warning("Level header %d: MusicSlot parameter is deprecated and will be removed.\nUse \"Music\" instead.", num); else if (fastcmp(word, "MUSICTRACK")) diff --git a/src/doomstat.h b/src/doomstat.h index 043d23a39..54e80a924 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -406,9 +406,11 @@ struct mapheader_t // Music information char musname[MAXMUSNAMES][7]; ///< Music tracks to play. First dimension is the track number, second is the music string. "" for no music. + char encoremusname[MAXMUSNAMES][7]; ///< Music tracks to play in Encore. First dimension is the track number, second is the music string. "" for no music. UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. UINT32 muspos; ///< Music position to jump to. UINT8 musname_size; ///< Number of music tracks defined + UINT8 encoremusname_size; ///< Number of Encore music tracks defined // Sky information UINT8 weather; ///< See preciptype_t diff --git a/src/lua_maplib.c b/src/lua_maplib.c index f6288e2c8..46a639b67 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -2580,12 +2580,29 @@ static int mapheaderinfo_get(lua_State *L) lua_rawseti(L, -2, 1 + j); } } + else if (fastcmp(field,"encoremusname")) // we create a table here because it saves us from a userdata nightmare + { + if (lua_compatmode) + { + lua_pushstring(L, header->encoremusname[0]); + return 1; + } + UINT8 j; + lua_createtable(L, header->encoremusname_size, 0); + for (j = 0; j < header->encoremusname_size; j++) + { + lua_pushstring(L, header->encoremusname[j]); + lua_rawseti(L, -2, 1 + j); + } + } else if (fastcmp(field,"mustrack")) lua_pushinteger(L, header->mustrack); else if (fastcmp(field,"muspos")) lua_pushinteger(L, header->muspos); else if (fastcmp(field,"musname_size")) lua_pushinteger(L, header->musname_size); + else if (fastcmp(field,"encoremusname_size")) + lua_pushinteger(L, header->encoremusname_size); else if (fastcmp(field,"weather")) lua_pushinteger(L, header->weather); else if (fastcmp(field,"skytexture")) diff --git a/src/p_setup.c b/src/p_setup.c index a92cb45af..fb58b96db 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -18,6 +18,7 @@ #include "byteptr.h" #include "g_game.h" +#include "g_mapnum.h" #include "info.h" #include "p_local.h" #include "p_setup.h" @@ -432,7 +433,7 @@ static void P_ClearMapHeaderLighting(mapheader_lighting_t *lighting) * \param i Map number to clear header for. * \sa P_ClearMapHeaderInfo */ -static void P_ClearSingleMapHeaderInfo(INT16 num) +static void P_ClearSingleMapHeaderInfo(mapnum_t num) { mapheaderinfo[num]->lvlttl[0] = '\0'; mapheaderinfo[num]->subttl[0] = '\0'; @@ -443,11 +444,15 @@ static void P_ClearSingleMapHeaderInfo(INT16 num) mapheaderinfo[num]->use_walltransfer = false; mapheaderinfo[num]->use_terrain = false; mapheaderinfo[num]->keywords[0] = '\0'; - for (int i = 0; i < MAXMUSNAMES; i++) - mapheaderinfo[num]->musname[i][0] = 0; + + memset(mapheaderinfo[num]->musname, 0, sizeof(mapheaderinfo[num]->musname)); + memset(mapheaderinfo[num]->encoremusname, 0, sizeof(mapheaderinfo[num]->encoremusname)); + mapheaderinfo[num]->mustrack = 0; mapheaderinfo[num]->muspos = 0; mapheaderinfo[num]->musname_size = 0; + mapheaderinfo[num]->encoremusname_size = 0; + mapheaderinfo[num]->weather = PRECIP_NONE; snprintf(mapheaderinfo[num]->skytexture, 5, "SKY1"); mapheaderinfo[num]->skytexture[4] = 0; diff --git a/src/s_sound.c b/src/s_sound.c index 68d54bc13..3afb81fec 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -2605,24 +2605,28 @@ void S_InitLevelMusic(boolean fromnetsave) INT16 usemusrng = 0; INT16 altmusonlysize = 0; + UINT8 truesize = (encoremode && mapheaderinfo[gamemap-1]->encoremusname_size) + ? mapheaderinfo[gamemap-1]->encoremusname_size + : mapheaderinfo[gamemap-1]->musname_size; + if (mapmusflags & MUSIC_RELOADRESET) { - if (mapheaderinfo[gamemap-1]->musname_size > 1) + if (truesize > 1) { - altmusonlysize = max(0, mapheaderinfo[gamemap-1]->musname_size - 1); + altmusonlysize = max(0, truesize - 1); } if (!fromnetsave) { if (demo.playback) { - if (mapheaderinfo[gamemap-1]->musname_size > 1) + if (truesize > 1) { P_RandomFixed(); } // mapmusrng has already been set by the demo; just make sure it's valid - if (mapmusrng >= mapheaderinfo[gamemap-1]->musname_size) + if (mapmusrng >= truesize) { mapmusrng = 0; } @@ -2630,9 +2634,9 @@ void S_InitLevelMusic(boolean fromnetsave) else { - if (mapheaderinfo[gamemap-1]->musname_size > 1) + if (truesize > 1) { - mapmusrng = P_RandomKey(mapheaderinfo[gamemap-1]->musname_size); + mapmusrng = P_RandomKey(truesize); } else mapmusrng = 0; @@ -2669,7 +2673,7 @@ void S_InitLevelMusic(boolean fromnetsave) if (mapheaderinfo[gamemap-1]->musname[0][0] == 0) strncpy(mapmusname, va("%sM", G_BuildMapName(gamemap)), 7); else - strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname[usemusrng], 7); + strncpy(mapmusname,(encoremode ? mapheaderinfo[gamemap-1]->encoremusname : mapheaderinfo[gamemap-1]->musname)[usemusrng], 7); mapmusname[6] = 0; mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);