mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-15 08:51:24 +00:00
- reworked music interface a bit.
Conmsidering how hard it is in Duke Nukem based games to modify the level music, there is now a setting for this in mussetting.txt to make the job easier and even allow setting level music in Redneck Rampage without replacing game data.
This commit is contained in:
parent
022c074ece
commit
22ccea8677
11 changed files with 82 additions and 54 deletions
|
@ -2099,11 +2099,16 @@ int sndTryPlaySpecialMusic(int nMusic)
|
|||
{
|
||||
int nEpisode = nMusic/kMaxLevels;
|
||||
int nLevel = nMusic%kMaxLevels;
|
||||
if (!sndPlaySong(gEpisodeInfo[nEpisode].at28[nLevel].atd0, true))
|
||||
if (sndPlaySong(gEpisodeInfo[nEpisode].at28[nLevel].at0, gEpisodeInfo[nEpisode].at28[nLevel].atd0, true))
|
||||
{
|
||||
strncpy(gGameOptions.zLevelSong, gEpisodeInfo[nEpisode].at28[nLevel].atd0, BMAX_PATH);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unable to stat the music.
|
||||
*gGameOptions.zLevelSong = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -403,9 +403,10 @@ bool levelTryPlayMusic(int nEpisode, int nLevel, bool bSetLevelSong)
|
|||
snprintf(buffer, BMAX_PATH, "blood%02i.ogg", gEpisodeInfo[nEpisode].at28[nLevel].ate0);
|
||||
else
|
||||
strncpy(buffer, gEpisodeInfo[nEpisode].at28[nLevel].atd0, BMAX_PATH);
|
||||
bool bReturn = !!sndPlaySong(buffer, true);
|
||||
if (!bReturn || bSetLevelSong)
|
||||
bool bReturn = !!sndPlaySong(gEpisodeInfo[nEpisode].at28[nLevel].atd0, buffer, true);
|
||||
if (bReturn || bSetLevelSong)
|
||||
strncpy(gGameOptions.zLevelSong, buffer, BMAX_PATH);
|
||||
else *gGameOptions.zLevelSong = 0;
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
|
|
|
@ -1793,7 +1793,7 @@ void UpdateMusicToggle(CGameMenuItemZBool *pItem)
|
|||
else
|
||||
{
|
||||
if (gGameStarted || gDemo.at1)
|
||||
sndPlaySong(gGameOptions.zLevelSong, true);
|
||||
sndPlaySong("*", gGameOptions.zLevelSong, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1847,7 +1847,7 @@ void SetSound(CGameMenuItemChain *pItem)
|
|||
sfxInit();
|
||||
|
||||
if (mus_enabled && (gGameStarted || gDemo.at1))
|
||||
sndPlaySong(gGameOptions.zLevelSong, true);
|
||||
sndPlaySong("*", gGameOptions.zLevelSong, true);
|
||||
}
|
||||
|
||||
void PreDrawSound(CGameMenuItem *pItem)
|
||||
|
|
|
@ -368,7 +368,7 @@ static int osdcmd_restartsound(osdcmdptr_t UNUSED(parm))
|
|||
sfxInit();
|
||||
|
||||
if (MusicEnabled() && (gGameStarted || gDemo.at1))
|
||||
sndPlaySong(gGameOptions.zLevelSong, true);
|
||||
sndPlaySong(nullptr, "*", true);
|
||||
|
||||
return OSDCMD_OK;
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ int nSongSize;
|
|||
bool bWaveMusic;
|
||||
int nWaveMusicHandle;
|
||||
|
||||
int sndPlaySong(const char *songName, bool bLoop)
|
||||
int sndPlaySong(const char *, const char* songName, bool bLoop)
|
||||
{
|
||||
if (!MusicEnabled())
|
||||
return 0;
|
||||
|
@ -225,13 +225,9 @@ void sndStopSong(void)
|
|||
nSongSize = 0;
|
||||
}
|
||||
#else
|
||||
int sndPlaySong(const char* songName, bool bLoop)
|
||||
int sndPlaySong(const char *mapname, const char* songName, bool bLoop)
|
||||
{
|
||||
if (!MusicEnabled())
|
||||
return 0;
|
||||
|
||||
Mus_Play(songName, bLoop);
|
||||
return 0;
|
||||
return Mus_Play(mapname, songName, bLoop);
|
||||
}
|
||||
|
||||
bool sndIsSongPlaying(void)
|
||||
|
|
|
@ -44,7 +44,7 @@ struct SFX
|
|||
};
|
||||
|
||||
int sndGetRate(int format);
|
||||
int sndPlaySong(const char *songName, bool bLoop);
|
||||
int sndPlaySong(const char *mapname, const char *songName, bool bLoop);
|
||||
bool sndIsSongPlaying(void);
|
||||
void sndFadeSong(int nTime);
|
||||
void sndSetMusicVolume(int nVolume);
|
||||
|
|
|
@ -73,6 +73,7 @@ MusPlayingInfo mus_playing;
|
|||
MusicAliasMap MusicAliases;
|
||||
MidiDeviceMap MidiDevices;
|
||||
MusicVolumeMap MusicVolumes;
|
||||
MusicAliasMap LevelMusicAliases;
|
||||
bool MusicPaused;
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -553,9 +554,36 @@ CCMD (stopmus)
|
|||
mus_playing.LastSong = ""; // forget the last played song so that it won't get restarted if some volume changes occur
|
||||
}
|
||||
|
||||
void Mus_Play(const char *fn, bool loop)
|
||||
static FString lastMusicLevel, lastMusic;
|
||||
int Mus_Play(const char *mapname, const char *fn, bool loop)
|
||||
{
|
||||
// Store the requested names for resuming.
|
||||
lastMusicLevel = mapname;
|
||||
lastMusic = fn;
|
||||
|
||||
if (!MusicEnabled())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// A restart was requested. Ignore the music name being passed and just try tp restart what got here last.
|
||||
if (*mapname == '*')
|
||||
{
|
||||
mapname = lastMusicLevel.GetChars();
|
||||
fn = lastMusic.GetChars();
|
||||
}
|
||||
// Allow per level music substitution.
|
||||
// Unlike some other engines like ZDoom or even Blood which use definition files, the music names in Duke Nukem are being defined in a CON script, making direct replacement a lot harder.
|
||||
// For most cases using $musicalias would be sufficient, but that method only works if a level actually has some music defined at all.
|
||||
// This way it can be done with an add-on definition lump even in cases like Redneck Rampage where no music definitions exist or where music gets reused for multiple levels but replacement is wanted individually.
|
||||
if (mapname && *mapname)
|
||||
{
|
||||
if (*mapname == '/') mapname++;
|
||||
FName *check = LevelMusicAliases.CheckKey(FName(mapname, true));
|
||||
if (check) fn = check->GetChars();
|
||||
}
|
||||
|
||||
S_ChangeMusic(fn, 0, loop, true);
|
||||
return mus_playing.handle != nullptr;
|
||||
}
|
||||
|
||||
void Mus_Stop()
|
||||
|
|
|
@ -50,11 +50,13 @@ enum SICommands
|
|||
SI_MusicVolume,
|
||||
SI_MidiDevice,
|
||||
SI_MusicAlias,
|
||||
SI_LevelMusic,
|
||||
};
|
||||
|
||||
|
||||
// This specifies whether Timidity or Windows playback is preferred for a certain song (only useful for Windows.)
|
||||
extern MusicAliasMap MusicAliases;
|
||||
extern MusicAliasMap LevelMusicAliases;
|
||||
extern MidiDeviceMap MidiDevices;
|
||||
extern MusicVolumeMap MusicVolumes;
|
||||
|
||||
|
@ -76,6 +78,7 @@ static const char *SICommandStrings[] =
|
|||
"$musicvolume",
|
||||
"$mididevice",
|
||||
"$musicalias",
|
||||
"$levelmusic",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -167,6 +170,20 @@ static void S_AddSNDINFO (int lump)
|
|||
}
|
||||
break;
|
||||
|
||||
case SI_LevelMusic: {
|
||||
sc.MustGetString();
|
||||
FName alias = sc.String;
|
||||
sc.MustGetString();
|
||||
FName mapped = sc.String;
|
||||
|
||||
// only set the alias if the lump it maps to exists.
|
||||
if (mapped == NAME_None || fileSystem.FindFile(sc.String) >= 0)
|
||||
{
|
||||
LevelMusicAliases[alias] = mapped;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SI_MidiDevice: {
|
||||
sc.MustGetString();
|
||||
FName nm = sc.String;
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
// Totally minimalistic interface - should be all the game modules need.
|
||||
|
||||
void Mus_Init();
|
||||
void Mus_Play(const char *fn, bool loop);
|
||||
int Mus_Play(const char *mapname, const char *fn, bool loop);
|
||||
void Mus_Stop();
|
||||
void Mus_SetPaused(bool on);
|
||||
|
|
|
@ -204,8 +204,8 @@ void S_MenuSound(void)
|
|||
S_PlaySound(s);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int S_PlayMusic(const char *fn)
|
||||
#if 0 // In case you desperately want the old system back... ;)
|
||||
static int S_PlayMusic(const char *, const char *fn, int loop)
|
||||
{
|
||||
if (!MusicEnabled())
|
||||
return 0;
|
||||
|
@ -323,13 +323,9 @@ void S_PauseMusic(bool paused)
|
|||
}
|
||||
|
||||
#else
|
||||
static int S_PlayMusic(const char* fn, bool looping = true)
|
||||
static int S_PlayMusic(const char *mapname, const char* fn, bool looping = true)
|
||||
{
|
||||
if (!MusicEnabled())
|
||||
return 0;
|
||||
|
||||
Mus_Play(fn, looping);
|
||||
return 1;
|
||||
return Mus_Play(mapname, fn, looping);
|
||||
}
|
||||
|
||||
void S_StopMusic(void)
|
||||
|
@ -362,16 +358,11 @@ bool S_TryPlayLevelMusic(unsigned int m)
|
|||
if (retval < 0)
|
||||
return false;
|
||||
|
||||
char const * musicfn = g_mapInfo[m].musicfn;
|
||||
|
||||
if (musicfn != NULL)
|
||||
{
|
||||
if (!S_PlayMusic(musicfn))
|
||||
if (!S_PlayMusic(g_mapInfo[m].filename, g_mapInfo[m].musicfn))
|
||||
{
|
||||
S_SetMusicIndex(m);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -390,7 +381,7 @@ int S_TryPlaySpecialMusic(unsigned int m)
|
|||
char const * musicfn = g_mapInfo[m].musicfn;
|
||||
if (musicfn != NULL)
|
||||
{
|
||||
if (!S_PlayMusic(musicfn))
|
||||
if (!S_PlayMusic(nullptr, musicfn))
|
||||
{
|
||||
S_SetMusicIndex(m);
|
||||
return 0;
|
||||
|
|
|
@ -166,8 +166,8 @@ void S_MenuSound(void)
|
|||
S_PlaySound(s);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int S_PlayMusic(const char *fn, int loop)
|
||||
#if 0 // In case you desperately want the old system back... ;)
|
||||
static int S_PlayMusic(const char *, const char *fn, int loop)
|
||||
{
|
||||
if (!MusicEnabled())
|
||||
return 0;
|
||||
|
@ -288,13 +288,9 @@ void S_PauseMusic(bool paused)
|
|||
|
||||
|
||||
#else
|
||||
static int S_PlayMusic(const char* fn, bool looping)
|
||||
static int S_PlayMusic(const char *mapname, const char* fn, bool looping = true)
|
||||
{
|
||||
if (!MusicEnabled())
|
||||
return 0;
|
||||
|
||||
Mus_Play(fn, looping);
|
||||
return 1;
|
||||
return Mus_Play(mapname, fn, looping);
|
||||
}
|
||||
|
||||
void S_StopMusic(void)
|
||||
|
@ -320,18 +316,12 @@ static void S_SetMusicIndex(unsigned int m)
|
|||
|
||||
bool S_TryPlayLevelMusic(unsigned int m)
|
||||
{
|
||||
if (RR)
|
||||
return 1;
|
||||
char const * musicfn = g_mapInfo[m].musicfn;
|
||||
|
||||
if (musicfn != NULL)
|
||||
{
|
||||
if (!S_PlayMusic(musicfn, 1))
|
||||
// For RR only explicitly invalidate the music name, but still allow the music code to run its own music substitution logic based on map names.
|
||||
if (!S_PlayMusic(g_mapInfo[m].filename,RR? nullptr : g_mapInfo[m].musicfn))
|
||||
{
|
||||
S_SetMusicIndex(m);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -352,7 +342,7 @@ int S_TryPlaySpecialMusic(unsigned int m)
|
|||
char const * musicfn = g_mapInfo[m].musicfn;
|
||||
if (musicfn != NULL)
|
||||
{
|
||||
if (!S_PlayMusic(musicfn, 1))
|
||||
if (!S_PlayMusic(nullptr, musicfn, 1))
|
||||
{
|
||||
S_SetMusicIndex(m);
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue