* Replaced MDT_PREFER_NATIVE/MDT_NATIVE by MDT_PREFER_MIDI/MDT_MIDI).

* Changed MidiDriver::createMidi so that if MD_ADLIB is passed, it
  now *does* instantiate the adlib driver.
* Rewrote MidiDriver::detectMusicDriver (code should be clearer now,
  and hopefully easier to adapt/maintain). Note that the behavior
  changed slightly (this may require some tweaking).
* Added MidiDriver::findMusicDriver which works similar to the old
  MidiDriver::parseMusicDriver but returns the full MidiDriverDescription
  and ignores all characters in the passed driver name following a colon ":".
* Changed MidiDriver::parseMusicDriver to use MidiDriver::findMusicDriver.
* Changed game engines to match the changes made to MidiDriver.
* Modified SCUMM engine to not record the selected midi/music driver
  (in _midiDriver), but rather the music *type* (in _musicType).

svn-id: r19859
This commit is contained in:
Max Horn 2005-12-30 14:18:21 +00:00
parent 2b156bd4c1
commit 60fcd5a171
11 changed files with 202 additions and 186 deletions

View file

@ -258,14 +258,13 @@ int KyraEngine::init(GameDetector &detector) {
_system->endGFXTransaction();
// for now we prefer MIDI-to-Adlib conversion over native midi
int midiDrv = MidiDriver::detectMusicDriver(MDT_NATIVE | MDT_ADLIB/* | MDT_PREFER_NATIVE*/);
bool native_mt32 = (ConfMan.getBool("native_mt32") || (midiDrv == MD_MT32));
int midiDrv = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB/* | MDT_PREFER_MIDI*/);
bool native_mt32 = ((midiDrv == MD_MT32) || ConfMan.getBool("native_mt32"));
MidiDriver *driver = MidiDriver::createMidi(midiDrv);
if (!driver) {
if (midiDriver == MD_ADLIB) {
// In this case we should play the Adlib tracks, but for now
// the automagic MIDI-to-Adlib conversion will do.
driver = MidiDriver_ADLIB_create(_mixer);
} else if (native_mt32) {
driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
}

View file

@ -431,15 +431,15 @@ int QueenEngine::init(GameDetector &detector) {
// Set mixer music volume to maximum, since music volume is regulated by MusicPlayer's MIDI messages
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, Audio::Mixer::kMaxMixerVolume);
int midiDriver = MidiDriver::detectMusicDriver(MDT_NATIVE | MDT_ADLIB | MDT_PREFER_NATIVE);
int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI);
bool native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32"));
MidiDriver *driver = MidiDriver::createMidi(midiDriver);
if (!driver)
driver = MidiDriver_ADLIB_create(_mixer);
else if (ConfMan.getBool("native_mt32") || (midiDriver == MD_MT32))
if (native_mt32)
driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
_music = new Music(driver, this);
_music->hasNativeMT32(ConfMan.getBool("native_mt32") || (midiDriver == MD_MT32));
_music->hasNativeMT32(native_mt32);
_sound = Sound::giveSound(_mixer, this, _resource->compression());
_walk = new Walk(this);

View file

@ -232,16 +232,12 @@ int SagaEngine::init(GameDetector &detector) {
_console = new Console(this);
// Graphics should be initialized before music
int midiDriver = MidiDriver::detectMusicDriver(MDT_NATIVE | MDT_ADLIB | MDT_PREFER_NATIVE);
bool native_mt32 = (ConfMan.getBool("native_mt32") || (midiDriver == MD_MT32));
bool adlib = false;
int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI);
bool native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32"));
bool adlib = (midiDriver == MD_ADLIB);
MidiDriver *driver = MidiDriver::createMidi(midiDriver);
if (!driver) {
driver = MidiDriver_ADLIB_create(_mixer);
adlib = true;
} else if (native_mt32)
if (native_mt32)
driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
_music = new Music(this, _mixer, driver, _musicVolume);

View file

@ -62,7 +62,6 @@
#endif
#include "scumm/verbs.h"
#include "sound/mididrv.h"
#include "sound/mixer.h"
#ifdef MACOSX
@ -93,7 +92,7 @@ struct ScummGameSettings {
const char *name;
const char *description;
byte id, version, heversion;
int midi; // MidiDriverType values
int midi; // MidiDriverFlags values
uint32 features;
Common::Platform platform;
@ -173,7 +172,7 @@ static const ScummGameSettings scumm_settings[] = {
/* Scumm Version 3 */
{"indy3", "Indiana Jones and the Last Crusade", GID_INDY3, 3, 0, MDT_PCSPK | MDT_ADLIB,
GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, Common::kPlatformPC},
{"loom", "Loom", GID_LOOM, 3, 0, MDT_PCSPK | MDT_ADLIB | MDT_NATIVE,
{"loom", "Loom", GID_LOOM, 3, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, Common::kPlatformPC},
/* Scumm Version 4 */
@ -182,24 +181,24 @@ static const ScummGameSettings scumm_settings[] = {
/* Scumm version 5, small header -- we treat these as V4 games, since internally
they really are much closer to the V4 games than to all other V5 games. */
{"monkey", "Monkey Island 1", GID_MONKEY_VGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_NATIVE,
{"monkey", "Monkey Island 1", GID_MONKEY_VGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
GF_SMALL_HEADER | GF_USE_KEY, Common::kPlatformPC},
/* Scumm version 5 */
{"monkey2", "Monkey Island 2: LeChuck's revenge", GID_MONKEY2, 5, 0, /*MDT_PCSPK |*/ MDT_ADLIB | MDT_NATIVE,
{"monkey2", "Monkey Island 2: LeChuck's revenge", GID_MONKEY2, 5, 0, /*MDT_PCSPK |*/ MDT_ADLIB | MDT_MIDI,
GF_USE_KEY, Common::kPlatformPC},
{"atlantis", "Indiana Jones and the Fate of Atlantis", GID_INDY4, 5, 0, MDT_ADLIB | MDT_NATIVE,
{"atlantis", "Indiana Jones and the Fate of Atlantis", GID_INDY4, 5, 0, MDT_ADLIB | MDT_MIDI,
GF_USE_KEY, Common::kPlatformPC},
/* Scumm Version 6 */
{"tentacle", "Day of the Tentacle", GID_TENTACLE, 6, 0, /*MDT_PCSPK |*/ MDT_ADLIB | MDT_NATIVE,
{"tentacle", "Day of the Tentacle", GID_TENTACLE, 6, 0, /*MDT_PCSPK |*/ MDT_ADLIB | MDT_MIDI,
GF_USE_KEY, Common::kPlatformPC},
{"samnmax", "Sam & Max", GID_SAMNMAX, 6, 0, /*MDT_PCSPK |*/ MDT_ADLIB | MDT_NATIVE,
{"samnmax", "Sam & Max", GID_SAMNMAX, 6, 0, /*MDT_PCSPK |*/ MDT_ADLIB | MDT_MIDI,
GF_USE_KEY, Common::kPlatformPC},
// {"test", "Test demo game", GID_SAMNMAX, 6, 0, /*MDT_PCSPK |*/ MDT_ADLIB | MDT_NATIVE, GF_NEW_OPCODES, Common::kPlatformUnknown},
// {"test", "Test demo game", GID_SAMNMAX, 6, 0, /*MDT_PCSPK |*/ MDT_ADLIB | MDT_MIDI, GF_NEW_OPCODES, Common::kPlatformUnknown},
#ifndef DISABLE_SCUMM_7_8
/* Scumm Version 7 */
@ -216,15 +215,15 @@ static const ScummGameSettings scumm_settings[] = {
#endif
// Humongous Entertainment Scumm Version 6
{"puttputt", "Putt-Putt Joins the Parade", GID_HEGAME, 6, 61, MDT_ADLIB | MDT_NATIVE,
{"puttputt", "Putt-Putt Joins the Parade", GID_HEGAME, 6, 61, MDT_ADLIB | MDT_MIDI,
GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformPC},
{"puttmoon", "Putt-Putt Goes to the Moon", GID_HEGAME, 6, 61, MDT_ADLIB | MDT_NATIVE,
{"puttmoon", "Putt-Putt Goes to the Moon", GID_HEGAME, 6, 61, MDT_ADLIB | MDT_MIDI,
GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformPC},
{"funpack", "Putt-Putt's Fun Pack", GID_FUNPACK, 6, 61, MDT_ADLIB | MDT_NATIVE,
{"funpack", "Putt-Putt's Fun Pack", GID_FUNPACK, 6, 61, MDT_ADLIB | MDT_MIDI,
GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformPC},
{"fbpack", "Fatty Bear's Fun Pack", GID_HEGAME, 6, 61, MDT_ADLIB | MDT_NATIVE,
{"fbpack", "Fatty Bear's Fun Pack", GID_HEGAME, 6, 61, MDT_ADLIB | MDT_MIDI,
GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformPC},
{"fbear", "Fatty Bear's Birthday Surprise", GID_FBEAR, 6, 61, MDT_ADLIB | MDT_NATIVE,
{"fbear", "Fatty Bear's Birthday Surprise", GID_FBEAR, 6, 61, MDT_ADLIB | MDT_MIDI,
GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformPC},
#ifndef DISABLE_HE
@ -549,11 +548,11 @@ static const ScummGameSettings multiple_versions_md5_settings[] = {
{"9c143c5905055d5df7a0f014ab379aee", "Putt-Putt Goes To The Moon (Windows Demo)", GID_HEGAME, 6, 70, MDT_NONE,
GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
{"0b3222aaa7efcf283eb621e0cefd26cc", "Putt-Putt Joins the Parade (Russian)", GID_HEGAME, 6, 60, MDT_ADLIB | MDT_NATIVE,
{"0b3222aaa7efcf283eb621e0cefd26cc", "Putt-Putt Joins the Parade (Russian)", GID_HEGAME, 6, 60, MDT_ADLIB | MDT_MIDI,
GF_USE_KEY, Common::kPlatformWindows},
{"31aa57f460a3d12429f0552a46a90b39", "Putt-Putt Joins the Parade (Demo)", GID_PUTTDEMO, 6, 60, MDT_ADLIB | MDT_NATIVE,
{"31aa57f460a3d12429f0552a46a90b39", "Putt-Putt Joins the Parade (Demo)", GID_PUTTDEMO, 6, 60, MDT_ADLIB | MDT_MIDI,
GF_USE_KEY, Common::kPlatformPC},
{"f40a7f495f59188ca57a9d1d50301bb6", "Putt-Putt Joins the Parade (Macintosh Demo)", GID_PUTTDEMO, 6, 60, MDT_ADLIB | MDT_NATIVE,
{"f40a7f495f59188ca57a9d1d50301bb6", "Putt-Putt Joins the Parade (Macintosh Demo)", GID_PUTTDEMO, 6, 60, MDT_ADLIB | MDT_MIDI,
GF_USE_KEY, Common::kPlatformPC},
{"6a30a07f353a75cdc602db27d73e1b42", "Putt-Putt Joins the Parade (Windows)", GID_HEGAME, 6, 70, MDT_NONE,
GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
@ -592,23 +591,23 @@ static const ScummGameSettings multiple_versions_md5_settings[] = {
{"d4b8ee426b1afd3e53bc0cf020418cf6", "Putt-Putt and Pep's Dog on a Stick (Updated)", GID_HEGAME, 6, 99, MDT_NONE,
GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
{"1d05cd189e4908f79b57e78a4402f292", "Monkey Island 1 (EGA)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_NATIVE,
{"1d05cd189e4908f79b57e78a4402f292", "Monkey Island 1 (EGA)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
{"49210e124e4c2b30f1290a9ef6306301", "Monkey Island 1 (EGA)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_NATIVE,
{"49210e124e4c2b30f1290a9ef6306301", "Monkey Island 1 (EGA)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
{"e98b982ceaf9d253d730bde8903233d6", "Monkey Island 1 (EGA De)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_NATIVE,
{"e98b982ceaf9d253d730bde8903233d6", "Monkey Island 1 (EGA De)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
{"fc6b6148e80d67939d9a18697c0f626a", "Monkey Island 1 (EGA De)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_NATIVE,
{"fc6b6148e80d67939d9a18697c0f626a", "Monkey Island 1 (EGA De)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
{"ce6a4cef315b20fef58a95bc40a2d8d3", "Monkey Island 1 (EGA Fr)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_NATIVE,
{"ce6a4cef315b20fef58a95bc40a2d8d3", "Monkey Island 1 (EGA Fr)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
{"aa7a07d94ae853f6460be4ce0a1bf530", "Monkey Island 1 (EGA Fr)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_NATIVE,
{"aa7a07d94ae853f6460be4ce0a1bf530", "Monkey Island 1 (EGA Fr)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
{"1dd3c11ea4439adfe681e4e405b624e1", "Monkey Island 1 (EGA Fr)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_NATIVE,
{"1dd3c11ea4439adfe681e4e405b624e1", "Monkey Island 1 (EGA Fr)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
{"477dbafbd66a53c98416dc01aef019ad", "Monkey Island 1 (EGA It)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_NATIVE,
{"477dbafbd66a53c98416dc01aef019ad", "Monkey Island 1 (EGA It)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
{"910e31cffb28226bd68c569668a0d6b4", "Monkey Island 1 (EGA Sp)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_NATIVE,
{"910e31cffb28226bd68c569668a0d6b4", "Monkey Island 1 (EGA Sp)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
{"c666a998af90d81db447eccba9f72c8d", "Monkey Island 1 (Atari)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK,
GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformAtariST},
@ -913,6 +912,7 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS
_heversion(gs.heversion),
_features(gs.features),
_platform(gs.platform),
_midi(gs.midi),
_substResFileNameIndex(substResFileNameIndex),
_substResFileNameIndexBundle(0),
_debugger(0),
@ -1179,7 +1179,7 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS
_haveActorSpeechMsg = false;
_useTalkAnims = false;
_defaultTalkDelay = 0;
_midiDriver = MD_NULL;
_musicType = MDT_NONE;
_tempMusic = 0;
_saveSound = 0;
memset(_extraBoxFlags, 0, sizeof(_extraBoxFlags));
@ -1447,8 +1447,6 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS
if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
_herculesBuf = (byte *)malloc(Common::kHercW * Common::kHercH);
}
_midi = gs.midi;
}
ScummEngine::~ScummEngine() {
@ -2117,10 +2115,30 @@ void ScummEngine_v99he::scummInit() {
#endif
void ScummEngine::setupMusic(int midi) {
_midiDriver = MidiDriver::detectMusicDriver(midi);
_native_mt32 = (ConfMan.getBool("native_mt32") || (_midiDriver == MD_MT32));
int midiDriver = MidiDriver::detectMusicDriver(midi);
_native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32"));
switch (midiDriver) {
case MD_NULL:
_musicType = MDT_NONE;
break;
case MD_PCSPK:
case MD_PCJR:
_musicType = MDT_PCSPK;
break;
case MD_TOWNS:
_musicType = MDT_TOWNS;
break;
case MD_ADLIB:
_musicType = MDT_ADLIB;
break;
default:
_musicType = MDT_MIDI;
break;
}
// FIXME: MD_TOWNS should not be _midi_native in the first place!! iMuse code needs to be restructured.
if ((_gameId == GID_TENTACLE) || (_gameId == GID_SAMNMAX) || (_midiDriver == MD_TOWNS))
if ((_gameId == GID_TENTACLE) || (_gameId == GID_SAMNMAX) || (midiDriver == MD_TOWNS))
_enable_gs = false;
else
_enable_gs = ConfMan.getBool("enable_gs");
@ -2129,10 +2147,9 @@ void ScummEngine::setupMusic(int midi) {
* automatically when samples need to be generated */
if (!_mixer->isReady()) {
warning("Sound mixer initialization failed\n");
if (_midiDriver == MD_ADLIB ||
_midiDriver == MD_PCSPK ||
_midiDriver == MD_PCJR) {
_midiDriver = MD_NULL;
if (_musicType == MDT_ADLIB || _musicType == MDT_PCSPK) {
midiDriver = MD_NULL;
_musicType = MDT_NONE;
warning("MIDI driver depends on sound mixer, switching to null MIDI driver\n");
}
}
@ -2154,22 +2171,24 @@ void ScummEngine::setupMusic(int midi) {
} else if ((_platform == Common::kPlatformAmiga) && (_version < 5)) {
_musicEngine = NULL;
} else if (_gameId == GID_MANIAC && (_version == 1)) {
_musicEngine = new Player_V1(this, _midiDriver != MD_PCSPK);
_musicEngine = new Player_V1(this, midiDriver != MD_PCSPK);
} else if (_version <= 2) {
_musicEngine = new Player_V2(this, _midiDriver != MD_PCSPK);;
} else if (((_midiDriver == MD_PCJR) || (_midiDriver == MD_PCSPK)) && ((_version > 2) && (_version < 5))) {
_musicEngine = new Player_V2(this, _midiDriver != MD_PCSPK);
_musicEngine = new Player_V2(this, midiDriver != MD_PCSPK);
} else if ((_musicType == MDT_PCSPK) && ((_version > 2) && (_version < 5))) {
_musicEngine = new Player_V2(this, midiDriver != MD_PCSPK);
} else if (_version > 2 && _heversion <= 61) {
MidiDriver *nativeMidiDriver = MidiDriver::createMidi(_midiDriver);
MidiDriver *nativeMidiDriver = 0;
MidiDriver *adlibMidiDriver = 0;
if (_musicType != MDT_ADLIB)
nativeMidiDriver = MidiDriver::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) {
nativeMidiDriver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
bool multi_midi = ConfMan.getBool("multi_midi") && _musicType != MDT_NONE && (midi & MDT_ADLIB);
if (_musicType == MDT_ADLIB || multi_midi) {
adlibMidiDriver = MidiDriver_ADLIB_create(_mixer);
adlibMidiDriver->property(MidiDriver::PROP_OLD_ADLIB, (_features & GF_SMALL_HEADER) ? 1 : 0);
} else
adlibMidiDriver = NULL;
}
_musicEngine = _imuse = IMuse::create(_system, nativeMidiDriver, adlibMidiDriver);
if (_imuse) {

View file

@ -32,6 +32,8 @@
#include "scumm/gfx.h"
#include "scumm/script.h"
#include "sound/mididrv.h"
namespace GUI {
class Dialog;
}
@ -1101,7 +1103,7 @@ protected:
bool _native_mt32;
bool _enable_gs;
int _midi;
int _midiDriver; // Use the MD_ values from mididrv.h
MidiDriverFlags _musicType;
bool _copyProtection;
bool _demoMode;
bool _confirmExit;

View file

@ -1362,7 +1362,7 @@ int ScummEngine::readSoundResource(int type, int idx) {
switch (basetag) {
case MKID('MIDI'):
case MKID('iMUS'):
if (_midiDriver != MD_PCSPK && _midiDriver != MD_PCJR) {
if (_musicType != MDT_PCSPK) {
_fileHandle->seek(-8, SEEK_CUR);
_fileHandle->read(res.createResource(type, idx, total_size + 8), total_size + 8);
return 1;
@ -1386,7 +1386,7 @@ int ScummEngine::readSoundResource(int type, int idx) {
break;
case MKID('ADL '):
pri = 1;
if (_midiDriver == MD_ADLIB)
if (_musicType == MDT_ADLIB)
pri = 10;
break;
case MKID('AMI '):
@ -1405,12 +1405,12 @@ int ScummEngine::readSoundResource(int type, int idx) {
break;
case MKID('SPK '):
pri = -1;
// if (_midiDriver == MD_PCSPK)
// if (_musicType == MDT_PCSPK)
// pri = 11;
break;
}
if ((_midiDriver == MD_PCSPK || _midiDriver == MD_PCJR) && pri != 11)
if ((_musicType == MDT_PCSPK) && pri != 11)
pri = -1;
debugC(DEBUG_RESOURCE, " tag: %s, total_size=%d, pri=%d", tag2str(TO_BE_32(tag)), size, pri);
@ -2333,7 +2333,7 @@ int ScummEngine::readSoundResourceSmallHeader(int type, int idx) {
}
}
if ((_midiDriver == MD_ADLIB) && ad_offs != 0) {
if ((_musicType == MDT_ADLIB) && ad_offs != 0) {
// AD resources have a header, instrument definitions and one MIDI track.
// We build an 'ADL ' resource from that:
// 8 bytes resource header
@ -2358,7 +2358,7 @@ int ScummEngine::readSoundResourceSmallHeader(int type, int idx) {
free(ptr);
return 1;
}
} else if (((_midiDriver == MD_PCJR) || (_midiDriver == MD_PCSPK)) && wa_offs != 0) {
} else if ((_musicType == MDT_PCSPK) && wa_offs != 0) {
if (_features & GF_OLD_BUNDLE) {
_fileHandle->seek(wa_offs, SEEK_SET);
_fileHandle->read(res.createResource(type, idx, wa_size), wa_size);

View file

@ -639,15 +639,14 @@ void ScummEngine_v99he::initScummVars() {
void ScummEngine::initScummVars() {
if (_heversion < 70 && _version <= 6) {
switch (_midiDriver) {
case MD_NULL:
switch (_musicType) {
case MDT_NONE:
VAR(VAR_SOUNDCARD) = 0;
break;
case MD_PCSPK:
case MD_PCJR:
case MDT_PCSPK:
VAR(VAR_SOUNDCARD) = 1;
break;
case MD_ADLIB:
case MDT_ADLIB:
VAR(VAR_SOUNDCARD) = 3;
break;
default:

View file

@ -560,14 +560,12 @@ int SimonEngine::init(GameDetector &detector) {
driver = MidiDriver::createMidi(MD_NULL); // Create fake MIDI driver for Simon1Amiga and Simon2CD32 for now
_native_mt32 = false;
} else {
int midiDriver = MidiDriver::detectMusicDriver(MDT_ADLIB | MDT_NATIVE);
int midiDriver = MidiDriver::detectMusicDriver(MDT_ADLIB | MDT_MIDI);
_native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32"));
driver = MidiDriver::createMidi(midiDriver);
_native_mt32 = (ConfMan.getBool("native_mt32") || (midiDriver == MD_MT32));
}
if (!driver)
driver = MidiDriver_ADLIB_create(_mixer);
else if (_native_mt32) {
driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
if (_native_mt32) {
driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
}
}
midi.mapMT32toGM (getGameType() == GType_SIMON1 && !_native_mt32);

View file

@ -317,13 +317,13 @@ int SkyEngine::init(GameDetector &detector) {
_systemVars.gameVersion = _skyDisk->determineGameVersion();
int midiDriver = MidiDriver::detectMusicDriver(MDT_ADLIB | MDT_NATIVE | MDT_PREFER_NATIVE);
int midiDriver = MidiDriver::detectMusicDriver(MDT_ADLIB | MDT_MIDI | MDT_PREFER_MIDI);
if (midiDriver == MD_ADLIB) {
_systemVars.systemFlags |= SF_SBLASTER;
_skyMusic = new AdlibMusic(_mixer, _skyDisk);
} else {
_systemVars.systemFlags |= SF_ROLAND;
if (ConfMan.getBool("native_mt32") || (midiDriver == MD_MT32))
if ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32"))
_skyMusic = new MT32Music(MidiDriver::createMidi(midiDriver), _skyDisk);
else
_skyMusic = new GmMusic(MidiDriver::createMidi(midiDriver), _skyDisk);

View file

@ -29,14 +29,12 @@
#include "sound/mididrv.h"
/** Internal list of all available 'midi' drivers. */
static const struct MidiDriverDescription midiDrivers[] = {
static const MidiDriverDescription s_musicDrivers[] = {
// The flags for the "auto" driver indicate that it is anything you want
// it to be.
// The flags for the "auto" & "null" drivers indicate that they are anything
// you want it to be.
{"auto", "Default", MD_AUTO, MDT_MIDI | MDT_PCSPK | MDT_ADLIB | MDT_TOWNS},
// The flags for the "null" driver indicate that it does nothing, really.
{"null", "No music", MD_NULL, MDT_NONE},
{"null", "No music", MD_NULL, MDT_MIDI | MDT_PCSPK | MDT_ADLIB | MDT_TOWNS},
#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__)
{"windows", "Windows MIDI", MD_WINDOWS, MDT_MIDI},
@ -51,10 +49,10 @@ static const struct MidiDriverDescription midiDrivers[] = {
#endif
#if defined(MACOSX)
{"qt", "QuickTime", MD_QTMUSIC, MDT_MIDI},
{"core", "CoreAudio", MD_COREAUDIO, MDT_MIDI},
// {"coreaudio", "CoreAudio", MD_COREAUDIO, MDT_MIDI},
{"coremidi", "CoreMIDI", MD_COREMIDI, MDT_MIDI},
{"qt", "QuickTime", MD_QTMUSIC, MDT_MIDI},
#endif
#if defined(PALMOS_MODE)
@ -73,7 +71,7 @@ static const struct MidiDriverDescription midiDrivers[] = {
#endif
// The flags for the "adlibe" driver indicate that it can do adlib and MIDI.
{"adlib", "Adlib", MD_ADLIB, MDT_ADLIB | MDT_MIDI},
{"adlib", "Adlib", MD_ADLIB, MDT_ADLIB},
{"pcspk", "PC Speaker", MD_PCSPK, MDT_PCSPK},
{"pcjr", "IBM PCjr", MD_PCJR, MDT_PCSPK},
{"towns", "FM Towns", MD_TOWNS, MDT_TOWNS},
@ -106,93 +104,101 @@ const byte MidiDriver::_gmToMt32[128] = {
};
const MidiDriverDescription *MidiDriver::getAvailableMidiDrivers() {
return midiDrivers;
return s_musicDrivers;
}
int MidiDriver::parseMusicDriver(const Common::String &str) {
const MidiDriverDescription &MidiDriver::findMusicDriver(const Common::String &str) {
if (str.isEmpty())
return -1;
return s_musicDrivers[0];
const char *s = str.c_str();
const MidiDriverDescription *md = getAvailableMidiDrivers();
int len = 0;
const MidiDriverDescription *md = s_musicDrivers;
// Scan for string end or a colon
while (s[len] != 0 && s[len] != ':')
len++;
while (md->name) {
if (!scumm_stricmp(md->name, s)) {
return md->id;
// Compare the string passed to us with the current table entry.
// We ignore any characters following an (optional) colon ':'
// contained in str.
if (!scumm_strnicmp(md->name, s, len)) {
return *md;
}
md++;
}
return -1;
return s_musicDrivers[0];
}
int MidiDriver::detectMusicDriver(int midiFlags) {
/*
TODO: The code in this method is very complicated and convuluted. Maybe we
can improve it.
First off, one needs to understand why it is so complex. It tries to honor
the user's music_driver config, but with the restrictions imposed by midiFlags.
Hence it must either select a suitable default driver (for example if
musicDriver is set to MD_AUTO), or it must try to fall back to a suitable
driver resp. the NULL driver.
Different games support different output drivers, as indicated by midiFlags.
Some of the occuring combinations are:
- TOWNS games always want towns or null
- some scumm games allow only pcspk, pcjr
- some scumm games allow pcspk, pcjr, adlib, MIDI
- some games allow adlib, MIDI
- some games only allow MIDI
- did I miss something?
My hope is that we can simplify the whole selection process by iterating over
the list of available drivers and looking at their "flags" member.
*/
int MidiDriver::parseMusicDriver(const Common::String &str) {
return findMusicDriver(str).id;
}
int musicDriver = parseMusicDriver(ConfMan.get("music_driver"));
/* Use the adlib sound driver if auto mode is selected,
* and the game is one of those that want adlib as
* default, OR if the game is an older game that doesn't
* support anything else anyway. */
if (musicDriver == MD_AUTO || musicDriver < 0) {
if (midiFlags & MDT_PREFER_MIDI) {
if (musicDriver == MD_AUTO) {
#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__)
musicDriver = MD_WINDOWS; // MD_WINDOWS is default MidiDriver on windows targets
#elif defined(MACOSX)
musicDriver = MD_COREAUDIO;
#elif defined(PALMOS_MODE) // must be before mac
musicDriver = MD_YPA1; // TODO : change this and use Zodiac driver when needed
#elif defined(__MORPHOS__)
musicDriver = MD_ETUDE;
#elif defined(_WIN32_WCE) || defined(UNIX) || defined(X11_BACKEND) || defined (__SYMBIAN32__)
// Always use MIDI emulation via adlib driver on CE and UNIX device
// TODO: We should, for the Unix targets, attempt to detect
// whether a sequencer is available, and use it instead.
musicDriver = MD_ADLIB;
#else
musicDriver = MD_NULL;
#endif
} else
static int getDefaultMIDIDriver() {
#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__)
return MD_WINDOWS;
#elif defined(MACOSX)
return MD_COREAUDIO;
#elif defined(PALMOS_MODE)
#if defined(COMPILE_CLIE)
return MD_YPA1;
#elif defined(COMPILE_ZODIAC)
return MD_ZODIAC;
#else
return MD_NULL;
#endif
#elif defined(__MORPHOS__)
return MD_ETUDE;
#else
return MD_NULL;
#endif
}
int MidiDriver::detectMusicDriver(int flags) {
// Query the selected music driver (defaults to MD_AUTO).
const MidiDriverDescription &md = findMusicDriver(ConfMan.get("music_driver"));
int musicDriver = md.id;
// Check whether the selected music driver is compatible with the
// given flags.
if (! (md.flags & flags))
musicDriver = MD_AUTO;
// If the selected driver is MD_AUTO, we try to determine
// a suitable and "optimal" music driver.
if (musicDriver == MD_AUTO) {
if (flags & MDT_PREFER_MIDI) {
// A MIDI music driver is preferred. Of course this implies
// that MIDI is actually listed in flags, so we verify that.
assert(flags & MDT_MIDI);
// Query the default MIDI driver. It's possible that there
// is none, in which case we revert to AUTO mode.
musicDriver = getDefaultMIDIDriver();
if (musicDriver == MD_NULL)
musicDriver = MD_AUTO;
}
if (musicDriver == MD_AUTO) {
// MIDI is not preferred, or no default MIDI device is available.
// In this case we first try the alternate drivers before checking
// for a 'real' MIDI driver.
if (flags & MDT_TOWNS)
musicDriver = MD_TOWNS;
else if (flags & MDT_ADLIB)
musicDriver = MD_ADLIB;
} else
musicDriver = MD_TOWNS;
else if (flags & MDT_PCSPK)
musicDriver = MD_PCJR;
else if (flags & MDT_MIDI)
musicDriver = getDefaultMIDIDriver();
else
musicDriver = MD_NULL;
}
}
bool nativeMidiDriver =
(musicDriver != MD_NULL && musicDriver != MD_ADLIB &&
musicDriver != MD_PCSPK && musicDriver != MD_PCJR &&
musicDriver != MD_TOWNS);
if (nativeMidiDriver && !(midiFlags & MDT_NATIVE))
musicDriver = MD_TOWNS;
if (musicDriver == MD_TOWNS && !(midiFlags & MDT_TOWNS))
musicDriver = MD_ADLIB;
if (musicDriver == MD_ADLIB && !(midiFlags & MDT_ADLIB))
musicDriver = MD_PCJR;
if ((musicDriver == MD_PCSPK || musicDriver == MD_PCJR) && !(midiFlags & MDT_PCSPK))
musicDriver = MD_NULL;
return musicDriver;
}
@ -201,18 +207,7 @@ MidiDriver *MidiDriver::createMidi(int midiDriver) {
switch(midiDriver) {
case MD_NULL: return MidiDriver_NULL_create();
// In the case of Adlib, we won't specify anything.
// IMuse is designed to set up its own Adlib driver
// if need be, and we only have to specify a native
// driver.
case MD_ADLIB: return NULL;
#ifdef USE_FLUIDSYNTH
case MD_FLUIDSYNTH: return MidiDriver_FluidSynth_create(g_engine->_mixer);
#endif
#ifdef USE_MT32EMU
case MD_MT32: return MidiDriver_MT32_create(g_engine->_mixer);
#endif
case MD_ADLIB: return MidiDriver_ADLIB_create(g_engine->_mixer);
case MD_TOWNS: return MidiDriver_YM2612_create(g_engine->_mixer);
@ -221,6 +216,15 @@ MidiDriver *MidiDriver::createMidi(int midiDriver) {
// don't create anything for now.
case MD_PCSPK:
case MD_PCJR: return NULL;
#ifdef USE_FLUIDSYNTH
case MD_FLUIDSYNTH: return MidiDriver_FluidSynth_create(g_engine->_mixer);
#endif
#ifdef USE_MT32EMU
case MD_MT32: return MidiDriver_MT32_create(g_engine->_mixer);
#endif
#if defined(PALMOS_MODE)
#if defined(COMPILE_CLIE)
case MD_YPA1: return MidiDriver_YamahaPa1_create();
@ -228,6 +232,7 @@ MidiDriver *MidiDriver::createMidi(int midiDriver) {
case MD_ZODIAC: return MidiDriver_Zodiac_create();
#endif
#endif
#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__)
case MD_WINDOWS: return MidiDriver_WIN_create();
#endif
@ -237,12 +242,10 @@ MidiDriver *MidiDriver::createMidi(int midiDriver) {
#if defined(UNIX) && !defined(__BEOS__) && !defined(MACOSX)
case MD_SEQ: return MidiDriver_SEQ_create();
#endif
#if (defined(MACOSX) || defined(macintosh)) && !defined(PALMOS_MODE)
case MD_QTMUSIC: return MidiDriver_QT_create();
#endif
#if defined(MACOSX)
case MD_QTMUSIC: return MidiDriver_QT_create();
case MD_COREAUDIO: return MidiDriver_CORE_create();
case MD_COREMIDI: return MidiDriver_CoreMIDI_create();
case MD_COREMIDI: return MidiDriver_CoreMIDI_create();
#endif
#if defined(UNIX) && defined(USE_ALSA)
case MD_ALSA: return MidiDriver_ALSA_create();

View file

@ -79,7 +79,7 @@ enum MidiDriverType {
* A set of flags to be passed to detectMusicDriver() which can be used to
* specify what kind of music driver is preferred / accepted.
*
* The flags (except for MDT_PREFER_NATIVE) indicate whether a given driver
* The flags (except for MDT_PREFER_MIDI) indicate whether a given driver
* type is acceptable. E.g. the TOWNS music driver could be returned by
* detectMusicDriver if and only if MDT_TOWNS is specified.
*
@ -91,10 +91,7 @@ enum MidiDriverFlags {
MDT_ADLIB = 1 << 1, // Adlib: Maps to MD_ADLIB
MDT_TOWNS = 1 << 2, // FM-TOWNS: Maps to MD_TOWNS
MDT_MIDI = 1 << 3, // Real MIDI
MDT_PREFER_MIDI = 1 << 4, // Real MIDI output is preferred
MDT_NATIVE = MDT_MIDI, // Alias for MDT_MIDI
MDT_PREFER_NATIVE = MDT_PREFER_MIDI // Alias for MDT_PREFER_MIDI
MDT_PREFER_MIDI = 1 << 4 // Real MIDI output is preferred
};
/**
@ -118,6 +115,9 @@ struct MidiDriverDescription {
*/
class MidiDriver {
public:
/** Find the music driver matching the given driver name/description. */
static const MidiDriverDescription &findMusicDriver(const Common::String &str);
/** Convert a string containing a music driver name into MIDI Driver type. */
static int parseMusicDriver(const Common::String &str);
@ -129,7 +129,7 @@ public:
static MidiDriver *createMidi(int midiDriver);
static int detectMusicDriver(int midiFlags);
static int detectMusicDriver(int flags);
public: