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 nEpisode = nMusic/kMaxLevels;
|
||||||
int nLevel = 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);
|
strncpy(gGameOptions.zLevelSong, gEpisodeInfo[nEpisode].at28[nLevel].atd0, BMAX_PATH);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Unable to stat the music.
|
||||||
|
*gGameOptions.zLevelSong = 0;
|
||||||
|
}
|
||||||
return 1;
|
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);
|
snprintf(buffer, BMAX_PATH, "blood%02i.ogg", gEpisodeInfo[nEpisode].at28[nLevel].ate0);
|
||||||
else
|
else
|
||||||
strncpy(buffer, gEpisodeInfo[nEpisode].at28[nLevel].atd0, BMAX_PATH);
|
strncpy(buffer, gEpisodeInfo[nEpisode].at28[nLevel].atd0, BMAX_PATH);
|
||||||
bool bReturn = !!sndPlaySong(buffer, true);
|
bool bReturn = !!sndPlaySong(gEpisodeInfo[nEpisode].at28[nLevel].atd0, buffer, true);
|
||||||
if (!bReturn || bSetLevelSong)
|
if (bReturn || bSetLevelSong)
|
||||||
strncpy(gGameOptions.zLevelSong, buffer, BMAX_PATH);
|
strncpy(gGameOptions.zLevelSong, buffer, BMAX_PATH);
|
||||||
|
else *gGameOptions.zLevelSong = 0;
|
||||||
return bReturn;
|
return bReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1793,7 +1793,7 @@ void UpdateMusicToggle(CGameMenuItemZBool *pItem)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (gGameStarted || gDemo.at1)
|
if (gGameStarted || gDemo.at1)
|
||||||
sndPlaySong(gGameOptions.zLevelSong, true);
|
sndPlaySong("*", gGameOptions.zLevelSong, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1847,7 +1847,7 @@ void SetSound(CGameMenuItemChain *pItem)
|
||||||
sfxInit();
|
sfxInit();
|
||||||
|
|
||||||
if (mus_enabled && (gGameStarted || gDemo.at1))
|
if (mus_enabled && (gGameStarted || gDemo.at1))
|
||||||
sndPlaySong(gGameOptions.zLevelSong, true);
|
sndPlaySong("*", gGameOptions.zLevelSong, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreDrawSound(CGameMenuItem *pItem)
|
void PreDrawSound(CGameMenuItem *pItem)
|
||||||
|
|
|
@ -368,7 +368,7 @@ static int osdcmd_restartsound(osdcmdptr_t UNUSED(parm))
|
||||||
sfxInit();
|
sfxInit();
|
||||||
|
|
||||||
if (MusicEnabled() && (gGameStarted || gDemo.at1))
|
if (MusicEnabled() && (gGameStarted || gDemo.at1))
|
||||||
sndPlaySong(gGameOptions.zLevelSong, true);
|
sndPlaySong(nullptr, "*", true);
|
||||||
|
|
||||||
return OSDCMD_OK;
|
return OSDCMD_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ int nSongSize;
|
||||||
bool bWaveMusic;
|
bool bWaveMusic;
|
||||||
int nWaveMusicHandle;
|
int nWaveMusicHandle;
|
||||||
|
|
||||||
int sndPlaySong(const char *songName, bool bLoop)
|
int sndPlaySong(const char *, const char* songName, bool bLoop)
|
||||||
{
|
{
|
||||||
if (!MusicEnabled())
|
if (!MusicEnabled())
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -225,13 +225,9 @@ void sndStopSong(void)
|
||||||
nSongSize = 0;
|
nSongSize = 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int sndPlaySong(const char* songName, bool bLoop)
|
int sndPlaySong(const char *mapname, const char* songName, bool bLoop)
|
||||||
{
|
{
|
||||||
if (!MusicEnabled())
|
return Mus_Play(mapname, songName, bLoop);
|
||||||
return 0;
|
|
||||||
|
|
||||||
Mus_Play(songName, bLoop);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sndIsSongPlaying(void)
|
bool sndIsSongPlaying(void)
|
||||||
|
|
|
@ -44,7 +44,7 @@ struct SFX
|
||||||
};
|
};
|
||||||
|
|
||||||
int sndGetRate(int format);
|
int sndGetRate(int format);
|
||||||
int sndPlaySong(const char *songName, bool bLoop);
|
int sndPlaySong(const char *mapname, const char *songName, bool bLoop);
|
||||||
bool sndIsSongPlaying(void);
|
bool sndIsSongPlaying(void);
|
||||||
void sndFadeSong(int nTime);
|
void sndFadeSong(int nTime);
|
||||||
void sndSetMusicVolume(int nVolume);
|
void sndSetMusicVolume(int nVolume);
|
||||||
|
|
|
@ -73,6 +73,7 @@ MusPlayingInfo mus_playing;
|
||||||
MusicAliasMap MusicAliases;
|
MusicAliasMap MusicAliases;
|
||||||
MidiDeviceMap MidiDevices;
|
MidiDeviceMap MidiDevices;
|
||||||
MusicVolumeMap MusicVolumes;
|
MusicVolumeMap MusicVolumes;
|
||||||
|
MusicAliasMap LevelMusicAliases;
|
||||||
bool MusicPaused;
|
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
|
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);
|
S_ChangeMusic(fn, 0, loop, true);
|
||||||
|
return mus_playing.handle != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mus_Stop()
|
void Mus_Stop()
|
||||||
|
|
|
@ -50,11 +50,13 @@ enum SICommands
|
||||||
SI_MusicVolume,
|
SI_MusicVolume,
|
||||||
SI_MidiDevice,
|
SI_MidiDevice,
|
||||||
SI_MusicAlias,
|
SI_MusicAlias,
|
||||||
|
SI_LevelMusic,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// This specifies whether Timidity or Windows playback is preferred for a certain song (only useful for Windows.)
|
// This specifies whether Timidity or Windows playback is preferred for a certain song (only useful for Windows.)
|
||||||
extern MusicAliasMap MusicAliases;
|
extern MusicAliasMap MusicAliases;
|
||||||
|
extern MusicAliasMap LevelMusicAliases;
|
||||||
extern MidiDeviceMap MidiDevices;
|
extern MidiDeviceMap MidiDevices;
|
||||||
extern MusicVolumeMap MusicVolumes;
|
extern MusicVolumeMap MusicVolumes;
|
||||||
|
|
||||||
|
@ -76,6 +78,7 @@ static const char *SICommandStrings[] =
|
||||||
"$musicvolume",
|
"$musicvolume",
|
||||||
"$mididevice",
|
"$mididevice",
|
||||||
"$musicalias",
|
"$musicalias",
|
||||||
|
"$levelmusic",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -167,6 +170,20 @@ static void S_AddSNDINFO (int lump)
|
||||||
}
|
}
|
||||||
break;
|
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: {
|
case SI_MidiDevice: {
|
||||||
sc.MustGetString();
|
sc.MustGetString();
|
||||||
FName nm = sc.String;
|
FName nm = sc.String;
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
// Totally minimalistic interface - should be all the game modules need.
|
// Totally minimalistic interface - should be all the game modules need.
|
||||||
|
|
||||||
void Mus_Init();
|
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_Stop();
|
||||||
void Mus_SetPaused(bool on);
|
void Mus_SetPaused(bool on);
|
||||||
|
|
|
@ -204,8 +204,8 @@ void S_MenuSound(void)
|
||||||
S_PlaySound(s);
|
S_PlaySound(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0 // In case you desperately want the old system back... ;)
|
||||||
static int S_PlayMusic(const char *fn)
|
static int S_PlayMusic(const char *, const char *fn, int loop)
|
||||||
{
|
{
|
||||||
if (!MusicEnabled())
|
if (!MusicEnabled())
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -323,13 +323,9 @@ void S_PauseMusic(bool paused)
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#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 Mus_Play(mapname, fn, looping);
|
||||||
return 0;
|
|
||||||
|
|
||||||
Mus_Play(fn, looping);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void S_StopMusic(void)
|
void S_StopMusic(void)
|
||||||
|
@ -362,16 +358,11 @@ bool S_TryPlayLevelMusic(unsigned int m)
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
char const * musicfn = g_mapInfo[m].musicfn;
|
if (!S_PlayMusic(g_mapInfo[m].filename, g_mapInfo[m].musicfn))
|
||||||
|
|
||||||
if (musicfn != NULL)
|
|
||||||
{
|
|
||||||
if (!S_PlayMusic(musicfn))
|
|
||||||
{
|
{
|
||||||
S_SetMusicIndex(m);
|
S_SetMusicIndex(m);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -390,7 +381,7 @@ int S_TryPlaySpecialMusic(unsigned int m)
|
||||||
char const * musicfn = g_mapInfo[m].musicfn;
|
char const * musicfn = g_mapInfo[m].musicfn;
|
||||||
if (musicfn != NULL)
|
if (musicfn != NULL)
|
||||||
{
|
{
|
||||||
if (!S_PlayMusic(musicfn))
|
if (!S_PlayMusic(nullptr, musicfn))
|
||||||
{
|
{
|
||||||
S_SetMusicIndex(m);
|
S_SetMusicIndex(m);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -166,8 +166,8 @@ void S_MenuSound(void)
|
||||||
S_PlaySound(s);
|
S_PlaySound(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0 // In case you desperately want the old system back... ;)
|
||||||
static int S_PlayMusic(const char *fn, int loop)
|
static int S_PlayMusic(const char *, const char *fn, int loop)
|
||||||
{
|
{
|
||||||
if (!MusicEnabled())
|
if (!MusicEnabled())
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -288,13 +288,9 @@ void S_PauseMusic(bool paused)
|
||||||
|
|
||||||
|
|
||||||
#else
|
#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 Mus_Play(mapname, fn, looping);
|
||||||
return 0;
|
|
||||||
|
|
||||||
Mus_Play(fn, looping);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void S_StopMusic(void)
|
void S_StopMusic(void)
|
||||||
|
@ -320,18 +316,12 @@ static void S_SetMusicIndex(unsigned int m)
|
||||||
|
|
||||||
bool S_TryPlayLevelMusic(unsigned int m)
|
bool S_TryPlayLevelMusic(unsigned int m)
|
||||||
{
|
{
|
||||||
if (RR)
|
// 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.
|
||||||
return 1;
|
if (!S_PlayMusic(g_mapInfo[m].filename,RR? nullptr : g_mapInfo[m].musicfn))
|
||||||
char const * musicfn = g_mapInfo[m].musicfn;
|
|
||||||
|
|
||||||
if (musicfn != NULL)
|
|
||||||
{
|
|
||||||
if (!S_PlayMusic(musicfn, 1))
|
|
||||||
{
|
{
|
||||||
S_SetMusicIndex(m);
|
S_SetMusicIndex(m);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -352,7 +342,7 @@ int S_TryPlaySpecialMusic(unsigned int m)
|
||||||
char const * musicfn = g_mapInfo[m].musicfn;
|
char const * musicfn = g_mapInfo[m].musicfn;
|
||||||
if (musicfn != NULL)
|
if (musicfn != NULL)
|
||||||
{
|
{
|
||||||
if (!S_PlayMusic(musicfn, 1))
|
if (!S_PlayMusic(nullptr, musicfn, 1))
|
||||||
{
|
{
|
||||||
S_SetMusicIndex(m);
|
S_SetMusicIndex(m);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue