diff --git a/src/s_sound.c b/src/s_sound.c index 6938fd639b84504e8c0e58ddc51d0de8cd901194..8b9927e9af9c74855af41c629744f209ab85d603 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -62,6 +62,8 @@ static void GameDigiMusic_OnChange(void); static void ModFilter_OnChange(void); +static lumpnum_t S_GetMusicLumpNum(const char *mname); + // commands for music and sound servers #ifdef MUSSERV consvar_t musserver_cmd = {"musserver_cmd", "musserver", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -1584,6 +1586,7 @@ static void S_AddMusicStackEntry(const char *mname, UINT16 mflags, boolean loopi music_stacks->position = (status == JT_MASTER ? position : S_GetMusicPosition()); music_stacks->tic = gametic; music_stacks->status = JT_MASTER; + music_stacks->mlumpnum = S_GetMusicLumpNum(music_stacks->musname); if (status == JT_MASTER) return; // we just added the user's entry here @@ -1601,6 +1604,7 @@ static void S_AddMusicStackEntry(const char *mname, UINT16 mflags, boolean loopi new_mst->position = position; new_mst->tic = gametic; new_mst->status = status; + new_mst->mlumpnum = S_GetMusicLumpNum(new_mst->musname); mst->next = new_mst; new_mst->prev = mst; @@ -1707,6 +1711,7 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst) entry->position = mapmusposition; entry->tic = gametic; entry->status = JT_MASTER; + entry->mlumpnum = S_GetMusicLumpNum(entry->musname); } if (entry->status == JT_MASTER) @@ -1730,7 +1735,10 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst) if (!music_stack_noposition) // HACK: Global boolean to toggle position resuming, e.g., de-superize newpos = entry->position + (S_GetMusicLength() ? (UINT32)((float)(gametic - entry->tic)/(float)TICRATE*(float)MUSICRATE) : 0); - if (newpos > 0 && S_MusicPlaying()) + // If the newly recalled music lumpnum does not match the lumpnum that we stored in stack, + // then discard the new position. That way, we will not recall an invalid position + // when the music is replaced or digital/MIDI is toggled. + if (newpos > 0 && S_MusicPlaying() && S_GetMusicLumpNum(entry->musname) == entry->mlumpnum) S_SetMusicPosition(newpos); else { @@ -1751,33 +1759,41 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst) /// Music Playback /// ------------------------ -static boolean S_LoadMusic(const char *mname) +static lumpnum_t S_GetMusicLumpNum(const char *mname) { - lumpnum_t mlumpnum; - void *mdata; - - if (S_MusicDisabled()) - return false; - if (!S_DigMusicDisabled() && S_DigExists(mname)) - mlumpnum = W_GetNumForName(va("o_%s", mname)); + return W_GetNumForName(va("o_%s", mname)); else if (!S_MIDIMusicDisabled() && S_MIDIExists(mname)) - mlumpnum = W_GetNumForName(va("d_%s", mname)); + return W_GetNumForName(va("d_%s", mname)); else if (S_DigMusicDisabled() && S_DigExists(mname)) { CONS_Alert(CONS_NOTICE, "Digital music is disabled!\n"); - return false; + return LUMPERROR; } else if (S_MIDIMusicDisabled() && S_MIDIExists(mname)) { CONS_Alert(CONS_NOTICE, "MIDI music is disabled!\n"); - return false; + return LUMPERROR; } else { CONS_Alert(CONS_ERROR, M_GetText("Music lump %.6s not found!\n"), mname); - return false; + return LUMPERROR; } +} + +static boolean S_LoadMusic(const char *mname) +{ + lumpnum_t mlumpnum; + void *mdata; + + if (S_MusicDisabled()) + return false; + + mlumpnum = S_GetMusicLumpNum(mname); + + if (mlumpnum == LUMPERROR) + return false; // load & register it mdata = W_CacheLumpNum(mlumpnum, PU_MUSIC); diff --git a/src/s_sound.h b/src/s_sound.h index 2d05a055d2e585e2f57cd31657f4463ca624f433..17887ef90a47129ed5b3c4f48b8767c59216c1ea 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -193,6 +193,7 @@ typedef struct musicstack_s UINT32 position; tic_t tic; UINT16 status; + lumpnum_t mlumpnum; struct musicstack_s *prev; struct musicstack_s *next;