diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 5be63ea21..eccd3a2f8 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -4480,14 +4480,9 @@ extern int G_StartRTS(int lumpNum, int localPlayer) return 0; } -void G_StartMusic(void) +void G_PrintCurrentMusic(void) { - int const levelNum = g_musicIndex; - Bassert(g_mapInfo[levelNum].musicfn != NULL); - - S_PlayMusic(g_mapInfo[levelNum].musicfn); - - Bsnprintf(apStrings[QUOTE_MUSIC], MAXQUOTELEN, "Playing %s", g_mapInfo[levelNum].musicfn); + Bsnprintf(apStrings[QUOTE_MUSIC], MAXQUOTELEN, "Playing %s", g_mapInfo[g_musicIndex].musicfn); P_DoQuote(QUOTE_MUSIC, g_player[myconnectindex].ps); } @@ -4721,17 +4716,18 @@ void G_HandleLocalKeys(void) { if (ridiculeNum == 5 && g_player[myconnectindex].ps->fta > 0 && g_player[myconnectindex].ps->ftq == QUOTE_MUSIC) { - const int32_t maxi = VOLUMEALL ? MUS_FIRST_SPECIAL : 6; + const unsigned int maxi = VOLUMEALL ? MUS_FIRST_SPECIAL : 6; + unsigned int MyMusicIndex = g_musicIndex; do { - g_musicIndex++; - if (g_musicIndex >= maxi) - g_musicIndex = 0; + ++MyMusicIndex; + if (MyMusicIndex >= maxi) + MyMusicIndex = 0; } - while (g_mapInfo[g_musicIndex].musicfn == NULL); + while (S_TryPlayLevelMusic(MyMusicIndex)); - G_StartMusic(); + G_PrintCurrentMusic(); return; } diff --git a/source/duke3d/src/game.h b/source/duke3d/src/game.h index 1a6b48935..017cc181a 100644 --- a/source/duke3d/src/game.h +++ b/source/duke3d/src/game.h @@ -555,7 +555,7 @@ static inline int G_GetViewscreenSizeShift(const uspritetype *tspr) #endif } -extern void G_StartMusic(void); +extern void G_PrintCurrentMusic(void); #ifdef LUNATIC void El_SetCON(const char *conluacode); diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index feaa5d808..22cf90f4b 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -1139,14 +1139,7 @@ static int G_StartTrackSlot(int const volumeNum, int const levelNum) { int trackNum = MAXLEVELS*volumeNum + levelNum; - if (g_mapInfo[trackNum].musicfn != NULL) - { - // Only set g_musicIndex on success. - g_musicIndex = trackNum; - S_PlayMusic(g_mapInfo[trackNum].musicfn); - - return 0; - } + return S_TryPlaySpecialMusic(trackNum); } return 1; diff --git a/source/duke3d/src/midi.cpp b/source/duke3d/src/midi.cpp index bc843191e..1fbc6542f 100644 --- a/source/duke3d/src/midi.cpp +++ b/source/duke3d/src/midi.cpp @@ -635,13 +635,6 @@ int32_t MIDI_PlaySong(char *song, int32_t loopflag) track *CurrentTrack; char *ptr; - if (_MIDI_SongLoaded) - MIDI_StopSong(); - - MPU_Init(MUSIC_SoundDevice); - - _MIDI_Loop = loopflag; - if (_MIDI_Funcs == NULL) return MIDI_NullMidiModule; @@ -652,12 +645,12 @@ int32_t MIDI_PlaySong(char *song, int32_t loopflag) headersize = _MIDI_ReadNumber(song, 4); song += 4; format = _MIDI_ReadNumber(song, 2); - _MIDI_NumTracks = _MIDI_ReadNumber(song + 2, 2); - _MIDI_Division = _MIDI_ReadNumber(song + 4, 2); - if (_MIDI_Division < 0) + int32_t My_MIDI_NumTracks = _MIDI_ReadNumber(song + 2, 2); + int32_t My_MIDI_Division = _MIDI_ReadNumber(song + 4, 2); + if (My_MIDI_Division < 0) { // If a SMPTE time division is given, just set to 96 so no errors occur - _MIDI_Division = 96; + My_MIDI_Division = 96; } if (format > MAX_FORMAT) @@ -665,22 +658,22 @@ int32_t MIDI_PlaySong(char *song, int32_t loopflag) ptr = song + headersize; - if (_MIDI_NumTracks == 0) + if (My_MIDI_NumTracks == 0) return MIDI_NoTracks; - _MIDI_TrackMemSize = _MIDI_NumTracks * sizeof(track); - _MIDI_TrackPtr = (track *)Xmalloc(_MIDI_TrackMemSize); + int32_t My_MIDI_TrackMemSize = My_MIDI_NumTracks * sizeof(track); + track * My_MIDI_TrackPtr = (track *)Xmalloc(My_MIDI_TrackMemSize); - CurrentTrack = _MIDI_TrackPtr; - numtracks = _MIDI_NumTracks; + CurrentTrack = My_MIDI_TrackPtr; + numtracks = My_MIDI_NumTracks; while (numtracks--) { if (B_UNBUF32(ptr) != MIDI_TRACK_SIGNATURE) { - DO_FREE_AND_NULL(_MIDI_TrackPtr); + DO_FREE_AND_NULL(My_MIDI_TrackPtr); - _MIDI_TrackMemSize = 0; + My_MIDI_TrackMemSize = 0; return MIDI_InvalidTrack; } @@ -692,6 +685,19 @@ int32_t MIDI_PlaySong(char *song, int32_t loopflag) CurrentTrack++; } + // at this point we know song load is successful + + if (_MIDI_SongLoaded) + MIDI_StopSong(); + + MPU_Init(MUSIC_SoundDevice); + + _MIDI_Loop = loopflag; + _MIDI_NumTracks = My_MIDI_NumTracks; + _MIDI_Division = My_MIDI_Division; + _MIDI_TrackMemSize = My_MIDI_TrackMemSize; + _MIDI_TrackPtr = My_MIDI_TrackPtr; + _MIDI_InitEMIDI(); _MIDI_ResetTracks(); diff --git a/source/duke3d/src/music.cpp b/source/duke3d/src/music.cpp index 1cd83d200..bfb2eadab 100644 --- a/source/duke3d/src/music.cpp +++ b/source/duke3d/src/music.cpp @@ -91,7 +91,7 @@ int32_t MUSIC_StopSong(void) int32_t MUSIC_PlaySong(char *song, int32_t loopflag) { - MUSIC_StopSong(); + MUSIC_SetErrorCode(MUSIC_Ok) if (MIDI_PlaySong(song, loopflag) != MIDI_Ok) { diff --git a/source/duke3d/src/osdcmds.cpp b/source/duke3d/src/osdcmds.cpp index 021a87601..7c2f6698b 100644 --- a/source/duke3d/src/osdcmds.cpp +++ b/source/duke3d/src/osdcmds.cpp @@ -400,10 +400,9 @@ static int32_t osdcmd_music(osdfuncparm_t const * const parm) return OSDCMD_OK; } - if (g_mapInfo[sel].musicfn != NULL) + if (!S_TryPlayLevelMusic(sel)) { - g_musicIndex = sel; - G_StartMusic(); + G_PrintCurrentMusic(); } else { diff --git a/source/duke3d/src/premap.cpp b/source/duke3d/src/premap.cpp index db02ef6a5..6d21ef30e 100644 --- a/source/duke3d/src/premap.cpp +++ b/source/duke3d/src/premap.cpp @@ -423,10 +423,7 @@ void G_CacheMapData(void) if (ud.recstat == 2) return; - if (g_mapInfo[MUS_LOADING].musicfn) - { - S_PlayMusic(g_mapInfo[MUS_LOADING].musicfn); - } + S_TryPlaySpecialMusic(MUS_LOADING); #if defined EDUKE32_TOUCH_DEVICES && defined USE_OPENGL polymost_glreset(); @@ -1404,7 +1401,7 @@ void G_NewGame(int volumeNum, int levelNum, int skillNum) VM_OnEventWithReturn(EVENT_NEWGAMESCREEN, g_player[myconnectindex].ps->i, myconnectindex, 0) == 0 && levelNum == 0 && volumeNum == 3 && ud.lockout == 0 && (G_GetLogoFlags() & LOGO_NOE4CUTSCENE)==0) { - S_PlayMusic(g_mapInfo[MUS_BRIEFING].musicfn); + S_PlaySpecialMusicOrNothing(MUS_BRIEFING); flushperms(); setview(0,0,xdim-1,ydim-1); @@ -1937,14 +1934,14 @@ int G_EnterLevel(int gameMode) if (ud.recstat != 2) { - if (g_mapInfo[mii].musicfn != NULL && - (g_mapInfo[g_musicIndex].musicfn == NULL || - Bstrcmp(g_mapInfo[g_musicIndex].musicfn, g_mapInfo[mii].musicfn) || - g_musicSize == 0 || - ud.last_level == -1)) - S_PlayMusic(g_mapInfo[mii].musicfn); - - g_musicIndex = mii; + if (g_mapInfo[g_musicIndex].musicfn == NULL || + g_mapInfo[mii].musicfn == NULL || // intentional, to pass control further while avoiding the strcmp on null + strcmp(g_mapInfo[g_musicIndex].musicfn, g_mapInfo[mii].musicfn) || + g_musicSize == 0 || + ud.last_level == -1) + { + S_PlayLevelMusicOrNothing(mii); + } } if (gameMode & (MODE_GAME|MODE_EOL)) diff --git a/source/duke3d/src/savegame.cpp b/source/duke3d/src/savegame.cpp index 4687cdfd9..65728ac04 100644 --- a/source/duke3d/src/savegame.cpp +++ b/source/duke3d/src/savegame.cpp @@ -2176,14 +2176,8 @@ static void postloadplayer(int32_t savegamep) if (ud.config.MusicToggle) { - if (g_mapInfo[musicIdx].musicfn != NULL && - (musicIdx != g_musicIndex /* || g_mapInfo[MUS_LOADING].musicfn */)) - { - S_StopMusic(); - - g_musicIndex = musicIdx; - S_PlayMusic(g_mapInfo[g_musicIndex].musicfn); - } + if (g_mapInfo[musicIdx].musicfn != NULL && musicIdx != g_musicIndex) + S_PlayLevelMusicOrNothing(musicIdx); S_PauseMusic(0); } diff --git a/source/duke3d/src/screens.cpp b/source/duke3d/src/screens.cpp index 904a5de26..65cd7941e 100644 --- a/source/duke3d/src/screens.cpp +++ b/source/duke3d/src/screens.cpp @@ -1507,10 +1507,7 @@ void G_DisplayLogo(void) } if (logoflags & LOGO_PLAYMUSIC) - { - g_musicIndex = MUS_INTRO; - S_PlayMusic(g_mapInfo[g_musicIndex].musicfn); - } + S_PlaySpecialMusicOrNothing(MUS_INTRO); if (!NAM) { diff --git a/source/duke3d/src/sdlmusic.cpp b/source/duke3d/src/sdlmusic.cpp index 459d04d98..9cb35d98e 100644 --- a/source/duke3d/src/sdlmusic.cpp +++ b/source/duke3d/src/sdlmusic.cpp @@ -408,6 +408,7 @@ static void sigchld_handler(int signo) int32_t MUSIC_PlaySong(char *song, int32_t loopflag) { // initprintf("MUSIC_PlaySong"); + // TODO: graceful failure MUSIC_StopSong(); if (external_midi) diff --git a/source/duke3d/src/sounds.cpp b/source/duke3d/src/sounds.cpp index 3dfd94d23..0fdaf7765 100644 --- a/source/duke3d/src/sounds.cpp +++ b/source/duke3d/src/sounds.cpp @@ -163,13 +163,11 @@ void S_RestartMusic(void) { if (ud.recstat != 2 && g_player[myconnectindex].ps->gm&MODE_GAME) { - if (g_mapInfo[g_musicIndex].musicfn != NULL) - S_PlayMusic(g_mapInfo[g_musicIndex].musicfn); + S_PlayLevelMusicOrNothing(g_musicIndex); } - else if (g_mapInfo[MUS_INTRO].musicfn != 0 && (G_GetLogoFlags() & LOGO_PLAYMUSIC)) + else if (G_GetLogoFlags() & LOGO_PLAYMUSIC) { - g_musicIndex = MUS_INTRO; - S_PlayMusic(g_mapInfo[MUS_INTRO].musicfn); + S_PlaySpecialMusicOrNothing(MUS_INTRO); } } @@ -186,62 +184,138 @@ void S_MenuSound(void) S_PlaySound(s); } -int32_t S_PlayMusic(const char *fn) +static int32_t S_PlayMusic(const char *fn) { if (!ud.config.MusicToggle || fn == NULL) - return 0; + return 1; int32_t fp = S_OpenAudio(fn, 0, 1); if (EDUKE32_PREDICT_FALSE(fp < 0)) { OSD_Printf(OSD_ERROR "S_PlayMusic(): error: can't open \"%s\" for playback!\n",fn); - return 0; + return 2; } - S_StopMusic(); - int32_t MusicLen = kfilelength(fp); if (EDUKE32_PREDICT_FALSE(MusicLen < 4)) { OSD_Printf(OSD_ERROR "S_PlayMusic(): error: empty music file \"%s\"\n", fn); kclose(fp); - return 0; + return 3; } - ALIGNED_FREE_AND_NULL(MusicPtr); // in case the following allocation was never freed - MusicPtr = (char *)Xaligned_alloc(16, MusicLen); - g_musicSize = kread(fp, (char *)MusicPtr, MusicLen); + char * MyMusicPtr = (char *)Xaligned_alloc(16, MusicLen); + int MyMusicSize = kread(fp, MyMusicPtr, MusicLen); - if (EDUKE32_PREDICT_FALSE(g_musicSize != MusicLen)) + if (EDUKE32_PREDICT_FALSE(MyMusicSize != MusicLen)) { OSD_Printf(OSD_ERROR "S_PlayMusic(): error: read %d bytes from \"%s\", expected %d\n", - g_musicSize, fn, MusicLen); + MyMusicSize, fn, MusicLen); kclose(fp); - g_musicSize = 0; - return 0; + ALIGNED_FREE_AND_NULL(MyMusicPtr); + return 4; } kclose(fp); - if (!Bmemcmp(MusicPtr, "MThd", 4)) + if (!Bmemcmp(MyMusicPtr, "MThd", 4)) { - MUSIC_PlaySong(MusicPtr, MUSIC_LoopSong); + int32_t retval = MUSIC_PlaySong(MyMusicPtr, MUSIC_LoopSong); + + if (retval != MUSIC_Ok) + { + ALIGNED_FREE_AND_NULL(MyMusicPtr); + return 5; + } + + if (MusicIsWaveform && MusicVoice >= 0) + { + FX_StopSound(MusicVoice); + MusicVoice = -1; + } + MusicIsWaveform = 0; + ALIGNED_FREE_AND_NULL(MusicPtr); + MusicPtr = MyMusicPtr; + g_musicSize = MyMusicSize; } else { int32_t const mvol = MASTER_VOLUME(ud.config.MusicVolume); - MusicVoice = FX_Play(MusicPtr, MusicLen, 0, 0, + int MyMusicVoice = FX_Play(MyMusicPtr, MusicLen, 0, 0, 0, mvol, mvol, mvol, FX_MUSIC_PRIORITY, MUSIC_ID); - if (MusicVoice > FX_Ok) - MusicIsWaveform = 1; + + if (MyMusicVoice <= FX_Ok) + { + ALIGNED_FREE_AND_NULL(MyMusicPtr); + return 5; + } + + if (MusicIsWaveform && MusicVoice >= 0) + FX_StopSound(MusicVoice); + + MUSIC_StopSong(); + + MusicVoice = MyMusicVoice; + MusicIsWaveform = 1; + ALIGNED_FREE_AND_NULL(MusicPtr); + MusicPtr = MyMusicPtr; + g_musicSize = MyMusicSize; } return 0; } +int S_TryPlayLevelMusic(unsigned int m) +{ + char const * musicfn = g_mapInfo[m].musicfn; + if (musicfn != NULL) + { + if (!S_PlayMusic(musicfn)) + { + g_musicIndex = m; + return 0; + } + } + + return 1; +} + +void S_PlayLevelMusicOrNothing(unsigned int m) +{ + if (S_TryPlayLevelMusic(m)) + { + S_StopMusic(); + g_musicIndex = m; + } +} + +int S_TryPlaySpecialMusic(unsigned int m) +{ + char const * musicfn = g_mapInfo[m].musicfn; + if (musicfn != NULL) + { + if (!S_PlayMusic(musicfn)) + { + g_musicIndex = m; + return 0; + } + } + + return 1; +} + +void S_PlaySpecialMusicOrNothing(unsigned int m) +{ + if (S_TryPlaySpecialMusic(m)) + { + S_StopMusic(); + g_musicIndex = m; + } +} + int32_t S_GetMusicPosition(void) { int32_t position = 0; diff --git a/source/duke3d/src/sounds.h b/source/duke3d/src/sounds.h index 29a491c94..8cd2e3f79 100644 --- a/source/duke3d/src/sounds.h +++ b/source/duke3d/src/sounds.h @@ -96,7 +96,10 @@ void S_MusicVolume(int32_t volume); void S_RestartMusic(void); void S_PauseMusic(int32_t onf); void S_PauseSounds(int32_t onf); -int32_t S_PlayMusic(const char *fn); +int S_TryPlayLevelMusic(unsigned int); +void S_PlayLevelMusicOrNothing(unsigned int); +int S_TryPlaySpecialMusic(unsigned int); +void S_PlaySpecialMusicOrNothing(unsigned int); int32_t S_PlaySound(int32_t num); int32_t S_PlaySound3D(int32_t num,int32_t i,const vec3_t *pos); void S_SoundShutdown(void);