From 8012a210708ed25d545e344cbdc22da0e19603c6 Mon Sep 17 00:00:00 2001 From: Oni Date: Sat, 11 Feb 2023 21:50:15 +0000 Subject: [PATCH] Merge branch 'alt-music' into 'master' Alt Music See merge request KartKrew/Kart!915 --- src/deh_soc.c | 21 ++++++++++++++++++--- src/doomstat.h | 11 ++++++++--- src/g_game.c | 1 + src/lua_maplib.c | 14 ++++++++++++-- src/lua_script.c | 5 +++++ src/p_saveg.c | 3 +++ src/p_setup.c | 23 +++++++++-------------- src/s_sound.c | 15 +++++++++++---- src/s_sound.h | 2 +- 9 files changed, 68 insertions(+), 27 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index 82dee04f2..bfbf260e7 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -51,6 +51,7 @@ // SRB2Kart #include "filesrch.h" // refreshdirmenu #include "k_follower.h" +#include "doomstat.h" // MAXMUSNAMES // Loops through every constant and operation in word and performs its calculations, returning the final value. fixed_t get_number(const char *word) @@ -1311,11 +1312,25 @@ void readlevelheader(MYFILE *f, INT32 num) else if (fastcmp(word, "MUSIC")) { if (fastcmp(word2, "NONE")) - mapheaderinfo[num-1]->musname[0] = 0; // becomes empty string + { + mapheaderinfo[num-1]->musname[0][0] = 0; // becomes empty string + mapheaderinfo[num-1]->musname_size = 0; + } else { - deh_strlcpy(mapheaderinfo[num-1]->musname, word2, - sizeof(mapheaderinfo[num-1]->musname), va("Level header %d: music", num)); + UINT8 j = 0; // i was declared elsewhere + tmp = strtok(word2, ","); + do { + if (j >= MAXMUSNAMES) + break; + deh_strlcpy(mapheaderinfo[num-1]->musname[j], tmp, + sizeof(mapheaderinfo[num-1]->musname[j]), va("Level header %d: 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-1]->musname_size = j; } } else if (fastcmp(word, "MUSICSLOT")) diff --git a/src/doomstat.h b/src/doomstat.h index 5acb023ee..f2db0b897 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -35,6 +35,7 @@ extern char mapmusname[7]; extern UINT16 mapmusflags; extern UINT32 mapmusposition; extern UINT32 mapmusresume; +extern UINT8 mapmusrng; #define MUSIC_TRACKMASK 0x0FFF // ----************ #define MUSIC_RELOADRESET 0x8000 // *--------------- #define MUSIC_FORCERESET 0x4000 // -*-------------- @@ -342,6 +343,8 @@ typedef struct angle_t light_angle; ///< Angle of directional wall lighting. } mapheader_lighting_t; +#define MAXMUSNAMES 3 // maximum definable music tracks per level + /** Map header information. */ typedef struct @@ -355,9 +358,6 @@ typedef struct INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end. INT16 marathonnext; ///< See nextlevel, but for Marathon mode. Necessary to support hub worlds ala SUGOI. char keywords[33]; ///< Keywords separated by space to search for. 32 characters. - char musname[7]; ///< Music track to play. "" 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. char forcecharacter[17]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable. UINT8 weather; ///< 0 = sunny day, 1 = storm, 2 = snow, 3 = rain, 4 = blank, 5 = thunder w/o rain, 6 = rain w/o lightning, 7 = heat wave. char skytexture[9]; ///< Sky texture to use. @@ -413,6 +413,11 @@ typedef struct // Music stuff. UINT32 musinterfadeout; ///< Fade out level music on intermission screen in milliseconds char musintername[7]; ///< Intermission screen music. + // Music information + char musname[MAXMUSNAMES][7]; ///< Music tracks to play. 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 char muspostbossname[7]; ///< Post-bossdeath music. UINT16 muspostbosstrack; ///< Post-bossdeath track. diff --git a/src/g_game.c b/src/g_game.c index 1af63a55e..b5d26de43 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -89,6 +89,7 @@ char mapmusname[7]; // Music name UINT16 mapmusflags; // Track and reset bit UINT32 mapmusposition; // Position to jump to UINT32 mapmusresume; +UINT8 mapmusrng; // Random selection result INT16 gamemap = 1; UINT32 maptol; diff --git a/src/lua_maplib.c b/src/lua_maplib.c index b98ddbb70..20552a20b 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -2498,12 +2498,22 @@ static int mapheaderinfo_get(lua_State *L) lua_pushinteger(L, header->marathonnext); else if (fastcmp(field,"keywords")) lua_pushstring(L, header->keywords); - else if (fastcmp(field,"musname")) - lua_pushstring(L, header->musname); + else if (fastcmp(field,"musname")) // we create a table here because it saves us from a userdata nightmare + { + UINT8 i; + lua_createtable(L, header->musname_size, 0); + for (i = 0; i < header->musname_size; i++) + { + lua_pushstring(L, header->musname[i]); + lua_rawseti(L, -2, 1 + i); + } + } 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,"musinterfadeout")) lua_pushinteger(L, header->musinterfadeout); else if (fastcmp(field,"musintername")) diff --git a/src/lua_script.c b/src/lua_script.c index f71741ef9..fddbcb12b 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -332,6 +332,9 @@ int LUA_PushGlobals(lua_State *L, const char *word) } else if (fastcmp(word,"mapmusposition")) { lua_pushinteger(L, mapmusposition); return 1; + } else if (fastcmp(word,"mapmusrng")) { + lua_pushinteger(L, mapmusrng); + return 1; // local player variables, by popular request } else if (fastcmp(word,"consoleplayer")) { // player controlling console (aka local player 1) if (!addedtogame || consoleplayer < 0 || !playeringame[consoleplayer]) @@ -460,6 +463,8 @@ int LUA_WriteGlobals(lua_State *L, const char *word) } else if (fastcmp(word, "mapmusflags")) mapmusflags = (UINT16)luaL_checkinteger(L, 2); + else if (fastcmp(word, "mapmusrng")) + mapmusrng = (UINT8)luaL_checkinteger(L, 2); // SRB2Kart else if (fastcmp(word,"racecountdown")) racecountdown = (tic_t)luaL_checkinteger(L, 2); diff --git a/src/p_saveg.c b/src/p_saveg.c index f16243699..9d178117b 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -4702,6 +4702,7 @@ static void P_NetArchiveMisc(boolean resending) WRITEUINT32(save_p, tokenlist); WRITEUINT8(save_p, encoremode); + WRITEUINT8(save_p, mapmusrng); WRITEUINT32(save_p, leveltime); WRITEUINT32(save_p, ssspheres); @@ -4863,6 +4864,8 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading) tokenlist = READUINT32(save_p); encoremode = (boolean)READUINT8(save_p); + + mapmusrng = READUINT8(save_p); if (!P_LoadLevel(true, reloading)) { diff --git a/src/p_setup.c b/src/p_setup.c index 220cc2971..aef4f0a3b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -96,6 +96,7 @@ #include "k_terrain.h" // TRF_TRIPWIRE #include "k_brightmap.h" #include "k_director.h" // K_InitDirector +#include "doomstat.h" // MAXMUSNAMES // Replay names have time #if !defined (UNDER_CE) @@ -377,9 +378,11 @@ static void P_ClearMapHeaderLighting(mapheader_lighting_t *lighting) static void P_ClearSingleMapHeaderInfo(INT16 i) { const INT16 num = (INT16)(i-1); + + UINT8 j; boolean exists = (mapheaderinfo[gamemap-1]->alreadyExists == true); - + mapheaderinfo[num]->lvlttl[0] = '\0'; mapheaderinfo[num]->selectheading[0] = '\0'; mapheaderinfo[num]->subttl[0] = '\0'; @@ -396,18 +399,11 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->ssspheres = 1; mapheaderinfo[num]->gravity = DEFAULT_GRAVITY; mapheaderinfo[num]->keywords[0] = '\0'; - snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i)); - mapheaderinfo[num]->musname[6] = 0; + for (j = 0; j < MAXMUSNAMES; j++) + mapheaderinfo[num]->musname[i][0] = 0; mapheaderinfo[num]->mustrack = 0; mapheaderinfo[num]->muspos = 0; - mapheaderinfo[num]->musinterfadeout = 0; - mapheaderinfo[num]->musintername[0] = 0; - mapheaderinfo[num]->muspostbossname[0] = 0; - mapheaderinfo[num]->muspostbosstrack = 0; - mapheaderinfo[num]->muspostbosspos = 0; - mapheaderinfo[num]->muspostbossfadein = 0; - mapheaderinfo[num]->musforcereset = -1; - mapheaderinfo[num]->forcecharacter[0] = '\0'; + mapheaderinfo[num]->musname_size = 0; mapheaderinfo[num]->weather = PRECIP_NONE; snprintf(mapheaderinfo[num]->skytexture, 5, "SKY1"); mapheaderinfo[num]->skytexture[4] = 0; @@ -7896,10 +7892,9 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) S_StartSound(NULL, sfx_s3k73); } - // As oddly named as this is, this handles music only. - // We should be fine starting it here. + // We should be fine starting music here. // Don't do this during titlemap, because the menu code handles music by itself. - S_StartEx(true); + S_InitLevelMusic(fromnetsave); } } diff --git a/src/s_sound.c b/src/s_sound.c index b8d813458..e4aca26b3 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -16,6 +16,7 @@ #include "command.h" #include "g_game.h" #include "m_argv.h" +#include "m_random.h" #include "r_main.h" // R_PointToAngle2() used to calc stereo sep. #include "r_skins.h" // for skins #include "i_system.h" @@ -2492,13 +2493,19 @@ boolean S_FadeOutStopMusic(UINT32 ms) // Kills playing sounds at start of level, // determines music if any, changes music. // -void S_StartEx(boolean reset) +void S_InitLevelMusic(boolean fromnetsave) { - (void)reset; if (mapmusflags & MUSIC_RELOADRESET) { - strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7); + if (!fromnetsave) + { + if (mapheaderinfo[gamemap-1]->musname_size > 1) + mapmusrng = P_RandomKey(mapheaderinfo[gamemap-1]->musname_size); + else + mapmusrng = 0; + } + strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname[mapmusrng], 7); mapmusname[6] = 0; mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK); mapmusposition = mapheaderinfo[gamemap-1]->muspos; @@ -2601,7 +2608,7 @@ static void Command_Tunes_f(void) } else if (!strcasecmp(tunearg, "-default")) { - tunearg = mapheaderinfo[gamemap-1]->musname; + tunearg = mapheaderinfo[gamemap-1]->musname[0]; track = mapheaderinfo[gamemap-1]->mustrack; } diff --git a/src/s_sound.h b/src/s_sound.h index 126d00c02..c81b271dd 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -118,7 +118,7 @@ void S_InitSfxChannels(INT32 sfxVolume); // void S_StopSounds(void); void S_ClearSfx(void); -void S_StartEx(boolean reset); +void S_InitLevelMusic(boolean reset); // // Basically a W_GetNumForName that adds "ds" at the beginning of the string. Returns a lumpnum.