To really, truly fix the multi-midi race condition, the adlib driver is now always created before iMuse initialisation. This necessitated removing the multimidi toggle from the debug console.

svn-id: r15912
This commit is contained in:
Jerome Fisher 2004-11-27 14:53:37 +00:00
parent 1a7ca2dc2a
commit 8d0ab890f8
5 changed files with 23 additions and 55 deletions

View File

@ -144,15 +144,6 @@ bool ScummDebugger::Cmd_IMuse(int argc, const char **argv) {
DebugPrintf("AAAIIIEEEEEE!\n");
DebugPrintf("Shutting down all music tracks\n");
return true;
} else if (!strcmp (argv[1], "multimidi")) {
if (argc > 2 && (!strcmp(argv[2], "on") || !strcmp(argv[2], "off"))) {
if (_vm->_imuse)
_vm->_imuse->property(IMuse::PROP_MULTI_MIDI, !strcmp(argv[2], "on"));
DebugPrintf("MultiMidi mode switched %s.\n", argv[2]);
} else {
DebugPrintf("Specify \"on\" or \"off\" to switch.\n");
}
return true;
} else if (!strcmp(argv[1], "play")) {
if (argc > 2 && (!strcmp(argv[2], "random") || atoi(argv[2]) != 0)) {
int sound = atoi(argv[2]);
@ -186,7 +177,6 @@ bool ScummDebugger::Cmd_IMuse(int argc, const char **argv) {
DebugPrintf("Available iMuse commands:\n");
DebugPrintf(" panic - Stop all music tracks\n");
DebugPrintf(" multimidi on/off - Toggle dual MIDI drivers\n");
DebugPrintf(" play # - Play a music resource\n");
DebugPrintf(" stop # - Stop a music resource\n");
return true;

View File

@ -1077,24 +1077,6 @@ uint32 IMuseInternal::property(int prop, uint32 value) {
initMT32(_midi_native);
break;
case IMuse::PROP_MULTI_MIDI:
_enable_multi_midi = (value > 0);
if (!_enable_multi_midi && _midi_native && _midi_adlib) {
MidiDriver *driver = _midi_adlib;
_midi_adlib = NULL;
int i;
for (i = 0; i < ARRAYSIZE(_players); ++i) {
if (_players[i].isActive() && _players[i].getMidiDriver() == driver)
_players[i].clear();
}
driver->close();
// FIXME: shouldn't we delete 'driver' here, too ?
} else if (_enable_multi_midi && _midi_adlib == NULL) {
_midi_adlib = MidiDriver_ADLIB_create(_mixer);
initMidiDriver(_midi_adlib);
}
break;
case IMuse::PROP_OLD_ADLIB_INSTRUMENTS:
_old_adlib_instruments = (value > 0);
break;
@ -1120,25 +1102,21 @@ void IMuseInternal::setBase(byte **base) {
_base_sounds = base;
}
IMuseInternal *IMuseInternal::create(OSystem *syst, SoundMixer *mixer, MidiDriver *native_midi) {
IMuseInternal *IMuseInternal::create(OSystem *syst, MidiDriver *nativeMidiDriver, MidiDriver *adlibMidiDriver) {
IMuseInternal *i = new IMuseInternal;
i->initialize(syst, mixer, native_midi);
i->initialize(syst, nativeMidiDriver, adlibMidiDriver);
return i;
}
int IMuseInternal::initialize(OSystem *syst, SoundMixer *mixer, MidiDriver *native_midi) {
int IMuseInternal::initialize(OSystem *syst, MidiDriver *native_midi, MidiDriver *adlib_midi) {
int i;
_mixer = mixer;
_midi_native = native_midi;
if (native_midi)
_midi_adlib = adlib_midi;
if (native_midi != NULL)
initMidiDriver(_midi_native);
if (!native_midi || _enable_multi_midi) {
_midi_adlib = MidiDriver_ADLIB_create(_mixer);
initMidiDriver(_midi_adlib);
} else {
_midi_adlib = NULL;
}
if (adlib_midi != NULL)
initMidiDriver(adlib_midi);
if (!_tempoFactor) _tempoFactor = 100;
_master_volume = 255;
@ -1785,8 +1763,8 @@ void IMuse::terminate() { in(); _target->terminate1(); out(); _target->terminate
// The IMuse::create method provides a front-end factory
// for creating IMuseInternal without exposing that class
// to the client.
IMuse *IMuse::create(OSystem *syst, SoundMixer *mixer, MidiDriver *midi) {
IMuseInternal *engine = IMuseInternal::create(syst, mixer, midi);
IMuse *IMuse::create(OSystem *syst, MidiDriver *nativeMidiDriver, MidiDriver *adlibMidiDriver) {
IMuseInternal *engine = IMuseInternal::create(syst, nativeMidiDriver, adlibMidiDriver);
return new IMuse(syst, engine);
}

View File

@ -29,7 +29,6 @@
class MidiDriver;
class OSystem;
class SoundMixer;
namespace Scumm {
@ -53,7 +52,6 @@ public:
enum {
PROP_TEMPO_BASE,
PROP_NATIVE_MT32,
PROP_MULTI_MIDI,
PROP_OLD_ADLIB_INSTRUMENTS,
PROP_LIMIT_PLAYERS,
PROP_RECYCLE_PLAYERS,
@ -79,7 +77,7 @@ public:
void terminate();
// Factory methods
static IMuse *create(OSystem *syst, SoundMixer *mixer, MidiDriver *midi);
static IMuse *create(OSystem *syst, MidiDriver *nativeMidiDriver, MidiDriver *adlibMidiDriver);
};
} // End of namespace Scumm

View File

@ -28,7 +28,6 @@
class MidiParser;
class OSystem;
class SoundMixer;
namespace Scumm {
@ -354,8 +353,6 @@ protected:
MidiDriver *_midi_native;
byte **_base_sounds;
SoundMixer *_mixer;
protected:
bool _paused;
@ -440,7 +437,7 @@ protected:
public:
IMuseInternal();
int initialize(OSystem *syst, SoundMixer *mixer, MidiDriver *midi);
int initialize(OSystem *syst, MidiDriver *nativeMidiDriver, MidiDriver *adlibMidiDriver);
void reallocateMidiChannels(MidiDriver *midi);
void setGlobalAdlibInstrument(byte slot, byte *data);
void copyGlobalAdlibInstrument(byte slot, Instrument *dest);
@ -466,7 +463,7 @@ public:
void setBase(byte **base);
uint32 property(int prop, uint32 value);
static IMuseInternal *create(OSystem *syst, SoundMixer *mixer, MidiDriver *midi);
static IMuseInternal *create(OSystem *syst, MidiDriver *nativeMidiDriver, MidiDriver *adlibMidiDriver);
};
} // End of namespace Scumm

View File

@ -1353,16 +1353,21 @@ void ScummEngine::setupMusic(int midi) {
} else if (((_midiDriver == MD_PCJR) || (_midiDriver == MD_PCSPK)) && ((_version > 2) && (_version < 5))) {
_musicEngine = new Player_V2(this, _midiDriver != MD_PCSPK);
} else if (_version > 2 && _heversion <= 60) {
MidiDriver *driver = GameDetector::createMidi(_midiDriver);
if (driver && _native_mt32)
driver->property (MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
_musicEngine = _imuse = IMuse::create(_system, _mixer, driver);
MidiDriver *nativeMidiDriver = GameDetector::createMidi(_midiDriver);
if (nativeMidiDriver != NULL && _native_mt32)
nativeMidiDriver->property (MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
bool multi_midi = ConfMan.getBool("multi_midi") && _midiDriver != MD_NULL && (midi & MDT_ADLIB);
MidiDriver *adlibMidiDriver;
if (nativeMidiDriver == NULL || multi_midi)
adlibMidiDriver = MidiDriver_ADLIB_create(_mixer);
else
adlibMidiDriver = NULL;
_musicEngine = _imuse = IMuse::create(_system, nativeMidiDriver, adlibMidiDriver);
if (_imuse) {
if (ConfMan.hasKey("tempo"))
_imuse->property(IMuse::PROP_TEMPO_BASE, ConfMan.getInt("tempo"));
_imuse->property(IMuse::PROP_OLD_ADLIB_INSTRUMENTS, (_features & GF_SMALL_HEADER) ? 1 : 0);
_imuse->property(IMuse::PROP_MULTI_MIDI, ConfMan.getBool("multi_midi") &&
_midiDriver != MD_NULL && (midi & MDT_ADLIB));
_imuse->property(IMuse::PROP_NATIVE_MT32, _native_mt32);
if (_features & GF_HUMONGOUS || midi == MDT_TOWNS) {
_imuse->property(IMuse::PROP_LIMIT_PLAYERS, 1);