mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 04:51:19 +00:00
- 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:
parent
670edb2356
commit
6420d82a58
5 changed files with 177 additions and 118 deletions
|
@ -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.
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue