Refactor all calls to S_PlayMusic.

This allows as much of the control flow as possible to fail gracefully without interruping currently playing music.

git-svn-id: https://svn.eduke32.com/eduke32@6619 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
hendricks266 2018-01-29 11:13:43 +00:00
parent 254b822003
commit d792054ce2
12 changed files with 153 additions and 93 deletions

View file

@ -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;
}

View file

@ -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);

View file

@ -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;

View file

@ -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();

View file

@ -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)
{

View file

@ -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
{

View file

@ -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) ||
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_PlayMusic(g_mapInfo[mii].musicfn);
g_musicIndex = mii;
ud.last_level == -1)
{
S_PlayLevelMusicOrNothing(mii);
}
}
if (gameMode & (MODE_GAME|MODE_EOL))

View file

@ -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);
}

View file

@ -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)
{

View file

@ -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)

View file

@ -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)
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;

View file

@ -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);