diff --git a/source/common/audio/music/music.cpp b/source/common/audio/music/music.cpp index 8749f4ba33..e05f9a0437 100644 --- a/source/common/audio/music/music.cpp +++ b/source/common/audio/music/music.cpp @@ -75,14 +75,12 @@ float saved_relative_volume = 1.0f; // this could be used to implement an ACS Fa MusicVolumeMap MusicVolumes; MidiDeviceMap MidiDevices; -static FileReader DefaultOpenMusic(const char* fn) +static int DefaultFindMusic(const char* fn) { - // This is the minimum needed to make the music system functional. - FileReader fr; - fr.OpenFile(fn); - return fr; + return -1; } -static MusicCallbacks mus_cb = { nullptr, DefaultOpenMusic }; + +MusicCallbacks mus_cb = { nullptr, DefaultFindMusic }; // PUBLIC DATA DEFINITIONS ------------------------------------------------- @@ -98,10 +96,44 @@ CVAR(Bool, mus_usereplaygain, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // changi // CODE -------------------------------------------------------------------- +//========================================================================== +// +// OpenMusic +// +// opens a FileReader for the music - used as a callback to keep +// implementation details out of the core player. +// +//========================================================================== + +static FileReader OpenMusic(const char* musicname) +{ + FileReader reader; + if (!FileExists(musicname)) + { + int lumpnum; + lumpnum = mus_cb.FindMusic(musicname); + if (lumpnum == -1) lumpnum = fileSystem.CheckNumForName(musicname, FileSys::ns_music); + if (lumpnum == -1) + { + Printf("Music \"%s\" not found\n", musicname); + } + else if (fileSystem.FileLength(lumpnum) != 0) + { + reader = fileSystem.ReopenFileReader(lumpnum); + } + } + else + { + // Load an external file. + reader.OpenFile(musicname); + } + return reader; +} + void S_SetMusicCallbacks(MusicCallbacks* cb) { mus_cb = *cb; - if (mus_cb.OpenMusic == nullptr) mus_cb.OpenMusic = DefaultOpenMusic; // without this we are dead in the water. + if (mus_cb.FindMusic == nullptr) mus_cb.FindMusic = DefaultFindMusic; // without this we are dead in the water. } int MusicEnabled() // int return is for scripting @@ -521,7 +553,7 @@ static void CheckReplayGain(const char *musicname, EMidiDevice playertype, const mod_dumb_mastervolume->Callback(); if (!mus_usereplaygain) return; - FileReader reader = mus_cb.OpenMusic(musicname); + FileReader reader = OpenMusic(musicname); if (!reader.isOpen()) return; int flength = (int)reader.GetLength(); auto mreader = GetMusicReader(reader); // this passes the file reader to the newly created wrapper. @@ -693,7 +725,7 @@ bool S_ChangeMusic(const char* musicname, int order, bool looping, bool force) } // opening the music must be done by the game because it's different depending on the game's file system use. - FileReader reader = mus_cb.OpenMusic(musicname); + FileReader reader = OpenMusic(musicname); if (!reader.isOpen()) return false; auto m = reader.Read(); reader.Seek(0, FileReader::SeekSet); @@ -718,7 +750,8 @@ bool S_ChangeMusic(const char* musicname, int order, bool looping, bool force) } else { - auto volp = MusicVolumes.CheckKey(musicname); + int lumpnum = mus_cb.FindMusic(musicname); + auto volp = MusicVolumes.CheckKey(lumpnum); if (volp) { mus_playing.musicVolume = *volp; diff --git a/source/common/audio/music/s_music.h b/source/common/audio/music/s_music.h index e697613cde..37a7c2de73 100644 --- a/source/common/audio/music/s_music.h +++ b/source/common/audio/music/s_music.h @@ -24,7 +24,7 @@ void S_PauseAllCustomStreams(bool on); struct MusicCallbacks { FString(*LookupFileName)(const char* fn, int &order); - FileReader(*OpenMusic)(const char* fn); + int(*FindMusic)(const char* fn); }; void S_SetMusicCallbacks(MusicCallbacks* cb); @@ -69,15 +69,17 @@ struct MidiDeviceSetting }; typedef TMap MidiDeviceMap; -typedef TMap MusicVolumeMap; +typedef TMap MusicVolumeMap; extern MidiDeviceMap MidiDevices; extern MusicVolumeMap MusicVolumes; +extern MusicCallbacks mus_cb; struct MusPlayingInfo { FString name; ZMusic_MusicStream handle; + int lumpnum; int baseorder; float musicVolume; bool loop; diff --git a/source/core/gamecvars.cpp b/source/core/gamecvars.cpp index 1f45522d20..0c8c52ad4f 100644 --- a/source/core/gamecvars.cpp +++ b/source/core/gamecvars.cpp @@ -129,7 +129,6 @@ CUSTOM_CVARD(Bool, snd_ambience, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_N } CVARD(Bool, snd_tryformats, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enables/disables automatic discovery of replacement sounds and music in .flac and .ogg formats") -CVARD(Bool, mus_restartonload, false, CVAR_ARCHIVE, "restart the music when loading a saved game with the same map or not") CVARD(Bool, mus_redbook, true, CVAR_ARCHIVE, "enables/disables redbook audio") CUSTOM_CVARD(Int, snd_speech, 1, CVAR_ARCHIVE, "enables/disables player speech") diff --git a/source/core/gamecvars.h b/source/core/gamecvars.h index 7273811618..4826d90623 100644 --- a/source/core/gamecvars.h +++ b/source/core/gamecvars.h @@ -55,7 +55,6 @@ EXTERN_CVAR(Int, demorec_difftics_cvar) EXTERN_CVAR(Bool, snd_ambience) EXTERN_CVAR(Bool, snd_tryformats) EXTERN_CVAR(Bool, mus_enabled) -EXTERN_CVAR(Bool, mus_restartonload) EXTERN_CVAR(Bool, mus_redbook) EXTERN_CVAR(Int, snd_numchannels) EXTERN_CVAR(Int, snd_numvoices) diff --git a/source/core/music/s_advsound.cpp b/source/core/music/s_advsound.cpp index b125580ad2..d600fe9990 100644 --- a/source/core/music/s_advsound.cpp +++ b/source/core/music/s_advsound.cpp @@ -50,6 +50,7 @@ #include "raze_music.h" #include "games/duke/src/sounds.h" + // MACROS ------------------------------------------------------------------ enum SICommands @@ -233,7 +234,7 @@ static void S_AddSNDINFO (int lump) case SI_MusicVolume: { sc.MustGetString(); - FName musname (sc.String); + int lumpnum = mus_cb.FindMusic(sc.String); if (!sc.CheckFloat()) { sc.MustGetString(); @@ -242,7 +243,7 @@ static void S_AddSNDINFO (int lump) if (!stricmp(p, "db")) sc.Float = dBToAmplitude((float)sc.Float); else sc.ScriptError("Bad value for music volume: %s", sc.String); } - MusicVolumes[musname] = (float)sc.Float; + if (lumpnum >= 0) MusicVolumes[lumpnum] = (float)sc.Float; } break; diff --git a/source/core/raze_music.cpp b/source/core/raze_music.cpp index f96f751a63..3647952c8a 100644 --- a/source/core/raze_music.cpp +++ b/source/core/raze_music.cpp @@ -113,65 +113,36 @@ int LookupMusic(const char* fn, bool onlyextended) // //========================================================================== -FileReader OpenMusic(const char* musicname) +int FindMusic(const char* musicname) { - FileReader reader; - if (!mus_restartonload) - { - // If the currently playing piece of music is the same, do not restart. Note that there's still edge cases where this may fail to detect identities. - if (mus_playing.handle != nullptr && lastStartedMusic.CompareNoCase(musicname) == 0 && mus_playing.loop) - return reader; - } lastStartedMusic = musicname; // remember the last piece of music that was requested to be played. - FString mus = MusicFileExists(musicname); - if (mus.IsNotEmpty()) - { - // Load an external file. - reader.OpenFile(mus.GetChars()); - } - if (!reader.isOpen()) + int lumpnum = LookupMusic(musicname); + if (mus_extendedlookup || lumpnum < 0) { - int lumpnum = LookupMusic(musicname); - if (mus_extendedlookup || lumpnum < 0) + if (lumpnum >= 0) { - if (lumpnum >= 0) - { - // EDuke also looks in a subfolder named after the main game resource. Do this as well if extended lookup is active. - auto rfn = fileSystem.GetResourceFileName(fileSystem.GetFileContainer(lumpnum)); - auto rfbase = ExtractFileBase(rfn); - FStringf aliasMusicname("music/%s/%s", rfbase.GetChars(), musicname); - int newlumpnum = LookupMusic(aliasMusicname.GetChars()); - if (newlumpnum >= 0) lumpnum = newlumpnum; - } - - // Always look in the 'music' subfolder as well. This gets used by multiple setups to store ripped CD tracks. - FStringf aliasMusicname("music/%s", musicname); - int newlumpnum = LookupMusic(aliasMusicname.GetChars(), lumpnum >= 0); + // EDuke also looks in a subfolder named after the main game resource. Do this as well if extended lookup is active. + auto rfn = fileSystem.GetResourceFileName(fileSystem.GetFileContainer(lumpnum)); + auto rfbase = ExtractFileBase(rfn); + FStringf aliasMusicname("music/%s/%s", rfbase.GetChars(), musicname); + int newlumpnum = LookupMusic(aliasMusicname.GetChars()); if (newlumpnum >= 0) lumpnum = newlumpnum; } - if (lumpnum == -1 && isSWALL()) - { - // Some Shadow Warrior distributions have the music in a subfolder named 'classic'. Check that, too. - FStringf aliasMusicname("classic/music/%s", musicname); - lumpnum = fileSystem.FindFile(aliasMusicname.GetChars()); - } - if (lumpnum > -1) - { - if (fileSystem.FileLength(lumpnum) >= 0) - { - reader = fileSystem.ReopenFileReader(lumpnum); - if (!reader.isOpen()) - { - Printf(TEXTCOLOR_RED "Unable to play music " TEXTCOLOR_WHITE "\"%s\"\n", musicname); - } - else if (printmusicinfo) Printf("Playing music from file system %s:%s\n", fileSystem.GetResourceFileFullName(fileSystem.GetFileContainer(lumpnum)), fileSystem.GetFileFullPath(lumpnum).c_str()); - } - } + // Always look in the 'music' subfolder as well. This gets used by multiple setups to store ripped CD tracks. + FStringf aliasMusicname("music/%s", musicname); + int newlumpnum = LookupMusic(aliasMusicname.GetChars(), lumpnum >= 0); + if (newlumpnum >= 0) lumpnum = newlumpnum; + } + + if (lumpnum == -1 && isSWALL()) + { + // Some Shadow Warrior distributions have the music in a subfolder named 'classic'. Check that, too. + FStringf aliasMusicname("classic/music/%s", musicname); + lumpnum = fileSystem.FindFile(aliasMusicname.GetChars()); } - else if (printmusicinfo) Printf("Playing music from external file %s\n", musicname); - return reader; + return lumpnum; } @@ -254,7 +225,7 @@ void Mus_InitMusic() static MusicCallbacks mus_cb = { LookupMusicCB, - OpenMusic + FindMusic }; S_SetMusicCallbacks(&mus_cb); }