- Fixed: After starting new music the music volume has to be reset so that

the song's relative volume takes effect.
- Removed the arbitrary 1024 bytes limit when the file being played is a MIDI
  file. I had a D_DM2TTL that's only 990 bytes.
- Restructured I_RegisterSong so that $mididevice works again and also supports
  selecting FMOD.


SVN r857 (trunk)
This commit is contained in:
Christoph Oelckers 2008-03-27 00:05:32 +00:00
parent 670edb2356
commit 6420d82a58
5 changed files with 177 additions and 118 deletions

View File

@ -1,4 +1,10 @@
March 26, 2008 (Changes by Graf Zahl)
- Fixed: After starting new music the music volume has to be reset so that
the song's relative volume takes effect.
- Removed the arbitrary 1024 bytes limit when the file being played is a MIDI
file. I had a D_DM2TTL that's only 990 bytes.
- Restructured I_RegisterSong so that $mididevice works again and also supports
selecting FMOD.
- Added Jim' Linux fix.
- Added MartinHowe's fix for mugshot display in status bars.

View File

@ -1261,10 +1261,11 @@ static void S_AddSNDINFO (int lump)
sc.MustGetString();
FName nm = sc.String;
sc.MustGetString();
if (sc.Compare("timidity")) MidiDevices[nm] = 1;
else if (sc.Compare("standard")) MidiDevices[nm] = 0;
else if (sc.Compare("opl")) MidiDevices[nm] = 2;
else if (sc.Compare("default")) MidiDevices[nm] = -1;
if (sc.Compare("timidity")) MidiDevices[nm] = MDEV_TIMIDITY;
else if (sc.Compare("fmod")) MidiDevices[nm] = MDEV_FMOD;
else if (sc.Compare("standard")) MidiDevices[nm] = MDEV_MMAPI;
else if (sc.Compare("opl")) MidiDevices[nm] = MDEV_OPL;
else if (sc.Compare("default")) MidiDevices[nm] = MDEV_DEFAULT;
else sc.ScriptError("Unknown MIDI device %s\n", sc.String);
}
break;

View File

@ -1307,10 +1307,10 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force)
{
int lumpnum = -1;
int offset, length;
int device = -1;
int device = MDEV_DEFAULT;
int * devp = MidiDevices.CheckKey(FName(musicname));
int *devp = MidiDevices.CheckKey(FName(musicname));
if (devp != NULL) device = *devp;
if (!FileExists (musicname))

View File

@ -311,6 +311,15 @@ ReverbContainer *S_FindEnvironment (const char *name);
ReverbContainer *S_FindEnvironment (int id);
void S_AddEnvironment (ReverbContainer *settings);
enum EMidiDevice
{
MDEV_DEFAULT = -1,
MDEV_MMAPI = 0,
MDEV_TIMIDITY = 1,
MDEV_OPL = 2,
MDEV_FMOD = 3,
};
typedef TMap<FName, int> MidiDeviceMap;
extern MidiDeviceMap MidiDevices;

View File

@ -192,6 +192,9 @@ void I_PlaySong (void *handle, int _looping, float rel_vol)
currSong = info;
else
currSong = NULL;
// Notify the sound system of the changed relative volume
snd_musicvolume.Callback();
}
@ -275,144 +278,182 @@ void *I_RegisterSong (const char *filename, char *musiccache, int offset, int le
memcpy(&id, &musiccache[0], 4);
}
#ifndef _WIN32
// non-windows platforms don't support MDEV_MIDI so map to MDEV_FMOD
if (device == MDEV_MMAPI) device = MDEV_FMOD;
#endif
// Check for MUS format
if (id == MAKE_ID('M','U','S',0x1a))
{
if (GSnd != NULL && device != 0 && device != 1 && (opl_enable || device == 2) )
if (GSnd != NULL)
{
info = new OPLMUSSong (file, musiccache, len);
/* MUS are played as:
- OPL:
- if explicitly selected by $mididevice
- when opl_enable is true and no midi device is set for the song
Timidity:
- if explicitly selected by $mididevice
- when snd_mididevice is -2 and no midi device is set for the song
FMod:
- if explicitly selected by $mididevice
- when snd_mididevice is -1 and no midi device is set for the song
- as fallback when both OPL and Timidity failed unless snd_mididevice is >= 0
MMAPI (Win32 only):
- if explicitly selected by $mididevice (non-Win32 redirects this to FMOD)
- when snd_mididevice is >= 0 and no midi device is set for the song
- as fallback when both OPL and Timidity failed and snd_mididevice is >= 0
*/
if ((opl_enable && device == MDEV_DEFAULT) || device == MDEV_OPL)
{
info = new OPLMUSSong (file, musiccache, len);
}
else if (device == MDEV_TIMIDITY || (device == MDEV_DEFAULT && snd_mididevice == -2))
{
info = new TimiditySong (file, musiccache, len);
}
if (info != NULL && !info->IsValid())
{
delete info;
info = NULL;
device = MDEV_DEFAULT;
}
if (info == NULL && (snd_mididevice == -1 || device == MDEV_FMOD) && device != MDEV_MMAPI)
{
TArray<BYTE> midi;
bool midi_made = false;
if (file == NULL)
{
midi_made = ProduceMIDI((BYTE *)musiccache, midi);
}
else
{
BYTE *mus = new BYTE[len];
size_t did_read = fread(mus, 1, len, file);
if (did_read == len)
{
midi_made = ProduceMIDI(mus, midi);
}
fseek(file, -(long)did_read, SEEK_CUR);
delete[] mus;
}
if (midi_made)
{
/*
FILE *f = fopen("latest.mid", "wb");
fwrite(&midi[0], 1, midi.Size(), f);
fclose(f);
*/
info = new StreamSong((char *)&midi[0], -1, midi.Size());
if (!info->IsValid())
{
delete info;
info = NULL;
}
}
}
}
#ifdef _WIN32
if (info == NULL)
{
#ifdef _WIN32
if (device == 1 && GSnd != NULL)
info = new MUSSong2 (file, musiccache, len);
}
#endif // _WIN32
}
// Check for MIDI format
else
{
if (id == MAKE_ID('M','T','h','d'))
{
// This is a midi file
// MIDI can't be played with OPL so use default.
if (device == MDEV_OPL) device = MDEV_DEFAULT;
/* MIDI are played as:
Timidity:
- if explicitly selected by $mididevice
- when snd_mididevice is -2 and no midi device is set for the song
FMod:
- if explicitly selected by $mididevice
- when snd_mididevice is -1 and no midi device is set for the song
- as fallback when Timidity failed unless snd_mididevice is >= 0
MMAPI (Win32 only):
- if explicitly selected by $mididevice (non-Win32 redirects this to FMOD)
- when snd_mididevice is >= 0 and no midi device is set for the song
- as fallback when Timidity failed and snd_mididevice is >= 0
*/
if ((device == MDEV_TIMIDITY || (snd_mididevice == -2 && device == MDEV_DEFAULT)) && GSnd != NULL)
{
info = new TimiditySong (file, musiccache, len);
if (!info->IsValid())
{
delete info;
info = NULL;
device = MDEV_DEFAULT;
}
}
if (info == NULL && (snd_mididevice >= 0 || device == 0))
{
info = new MUSSong2 (file, musiccache, len);
}
else if (info == NULL && GSnd != NULL)
#endif // _WIN32
{
if (snd_mididevice == -1)
{
TArray<BYTE> midi;
bool midi_made = false;
if (file == NULL)
{
midi_made = ProduceMIDI((BYTE *)musiccache, midi);
}
else
{
BYTE *mus = new BYTE[len];
size_t did_read = fread(mus, 1, len, file);
if (did_read == len)
{
midi_made = ProduceMIDI(mus, midi);
}
fseek(file, -(long)did_read, SEEK_CUR);
delete[] mus;
}
if (midi_made)
{
FILE *f = fopen("latest.mid", "wb");
fwrite(&midi[0], 1, midi.Size(), f);
fclose(f);
info = new StreamSong((char *)&midi[0], -1, midi.Size());
if (!info->IsValid())
{
delete info;
info = NULL;
}
}
}
if (info == NULL)
{
info = new TimiditySong (file, musiccache, len);
}
}
}
}
// Check for MIDI format
else if (id == MAKE_ID('M','T','h','d'))
{
// This is a midi file
#ifdef _WIN32
if (device == 1 && GSnd != NULL)
{
info = new TimiditySong (file, musiccache, len);
if (!info->IsValid())
if (info == NULL && device != MDEV_FMOD && (snd_mididevice >= 0 || device == MDEV_MMAPI))
{
delete info;
info = NULL;
info = new MIDISong2 (file, musiccache, len);
}
}
else if (info == NULL && (snd_mididevice >= 0 || device == 0))
{
info = new MIDISong2 (file, musiccache, len);
}
else if (info == NULL && GSnd != NULL)
#endif // _WIN32
}
// Check for RDosPlay raw OPL format
else if (id == MAKE_ID('R','A','W','A') && len >= 12)
{
if (snd_mididevice != -1)
DWORD fullsig[2];
if (file != NULL)
{
info = new TimiditySong (file, musiccache, len);
if (fread (fullsig, 4, 2, file) != 2)
{
fclose (file);
return 0;
}
fseek (file, -8, SEEK_CUR);
}
else
{
memcpy(fullsig, musiccache, 8);
}
if (fullsig[1] == MAKE_ID('D','A','T','A'))
{
info = new OPLMUSSong (file, musiccache, len);
}
}
}
// Check for RDosPlay raw OPL format
else if (id == MAKE_ID('R','A','W','A') && len >= 12)
{
DWORD fullsig[2];
if (file != NULL)
// Check for Martin Fernandez's modified IMF format
else if (id == MAKE_ID('A','D','L','I'))
{
if (fread (fullsig, 4, 2, file) != 2)
char fullhead[6];
if (file != NULL)
{
fclose (file);
return 0;
if (fread (fullhead, 1, 6, file) != 6)
{
fclose (file);
return 0;
}
fseek (file, -6, SEEK_CUR);
}
fseek (file, -8, SEEK_CUR);
}
else
{
memcpy(fullsig, musiccache, 8);
}
if (fullsig[1] == MAKE_ID('D','A','T','A'))
{
info = new OPLMUSSong (file, musiccache, len);
}
}
// Check for Martin Fernandez's modified IMF format
else if (id == MAKE_ID('A','D','L','I'))
{
char fullhead[6];
if (file != NULL)
{
if (fread (fullhead, 1, 6, file) != 6)
else
{
fclose (file);
return 0;
memcpy(fullhead, musiccache, 6);
}
if (fullhead[4] == 'B' && fullhead[5] == 1)
{
info = new OPLMUSSong (file, musiccache, len);
}
fseek (file, -6, SEEK_CUR);
}
else
{
memcpy(fullhead, musiccache, 6);
}
if (fullhead[4] == 'B' && fullhead[5] == 1)
{
info = new OPLMUSSong (file, musiccache, len);
}
}
@ -440,12 +481,13 @@ void *I_RegisterSong (const char *filename, char *musiccache, int offset, int le
}
}
}
// no FMOD => no modules/streams
// 1024 bytes is an arbitrary restriction. It's assumed that anything
// smaller than this can't possibly be a valid music file if it hasn't
// been identified already, so don't even bother trying to load it.
if (info == NULL && GSnd != NULL && len >= 1024)
// Of course MIDIs shorter than 1024 bytes should pass.
if (info == NULL && GSnd != NULL && (len >= 1024 || id == MAKE_ID('M','T','h','d')))
{
// Let FMOD figure out what it is.
if (file != NULL)
@ -457,6 +499,7 @@ void *I_RegisterSong (const char *filename, char *musiccache, int offset, int le
}
}
if (info && !info->IsValid ())
{
delete info;