diff options
-rw-r--r-- | scumm/imuse.cpp | 75 | ||||
-rw-r--r-- | scumm/imuse.h | 4 | ||||
-rw-r--r-- | scumm/imuse_internal.h | 8 | ||||
-rw-r--r-- | scumm/imuse_player.cpp | 20 | ||||
-rw-r--r-- | scumm/scummvm.cpp | 6 | ||||
-rw-r--r-- | scumm/sound.cpp | 63 |
6 files changed, 86 insertions, 90 deletions
diff --git a/scumm/imuse.cpp b/scumm/imuse.cpp index c67949b134..75098556f3 100644 --- a/scumm/imuse.cpp +++ b/scumm/imuse.cpp @@ -49,6 +49,8 @@ _base_sounds (0), _paused (false), _initialized (false), _tempoFactor (0), +_player_limit (ARRAYSIZE(_players)), +_recycle_players (false), _queue_end (0), _queue_pos (0), _queue_sound (0), @@ -89,7 +91,7 @@ MidiDriver *IMuseInternal::getMidiDriver() { return driver; } -byte *IMuseInternal::findTag(int sound, char *tag, int index) { +byte *IMuseInternal::findStartOfSound (int sound) { byte *ptr = NULL; int32 size, pos; @@ -97,7 +99,7 @@ byte *IMuseInternal::findTag(int sound, char *tag, int index) { ptr = _base_sounds[sound]; if (ptr == NULL) { - debug(1, "IMuseInternal::findTag completely failed finding sound %d", sound); + debug (1, "IMuseInternal::findStartOfSound(): Sound %d doesn't exist!", sound); return NULL; } @@ -106,16 +108,18 @@ byte *IMuseInternal::findTag(int sound, char *tag, int index) { size = READ_BE_UINT32_UNALIGNED(ptr); ptr += 4; + // Okay, we're looking for one of those things: either + // an 'MThd' tag (for SMF), or a 'FORM' tag (for XMIDI). + size = 48; // Arbitrary; we should find our tag within the first 48 bytes of the resource pos = 0; - while (pos < size) { - if (!memcmp(ptr + pos, tag, 4) && !index--) - return ptr + pos + 8; - pos += READ_BE_UINT32_UNALIGNED(ptr + pos + 4) + 8; + if (!memcmp (ptr + pos, "MThd", 4) || !memcmp (ptr + pos, "FORM", 4)) + return ptr + pos; + ++pos; // We could probably iterate more intelligently } - debug(3, "IMuseInternal::findTag failed finding sound %d", sound); - return NULL; + debug(3, "IMuseInternal::findStartOfSound(): Failed to align on sound %d!", sound); + return 0; } bool IMuseInternal::isMT32(int sound) { @@ -219,6 +223,14 @@ bool IMuseInternal::startSound(int sound) { return false; } + // Not sure exactly what the old code was doing, + // but we'll go ahead and do a similar check. + mdhd = findStartOfSound (sound); + if (!mdhd) { + debug (2, "IMuseInternal::startSound(): Couldn't find sound %d!", sound); + return false; + } +/* mdhd = findTag(sound, MDHD_TAG, 0); if (!mdhd) { mdhd = findTag(sound, MDPG_TAG, 0); @@ -227,6 +239,7 @@ bool IMuseInternal::startSound(int sound) { return false; } } +*/ // Check which MIDI driver this track should use. // If it's NULL, it ain't something we can play. @@ -257,7 +270,7 @@ Player *IMuseInternal::allocate_player(byte priority) { int i; byte bestpri = 255; - for (i = ARRAYSIZE(_players); i != 0; i--, player++) { + for (i = _player_limit; i != 0; i--, player++) { if (!player->isActive()) return player; if (player->getPriority() < bestpri) { @@ -266,7 +279,7 @@ Player *IMuseInternal::allocate_player(byte priority) { } } - if (bestpri < priority) + if (bestpri < priority || _recycle_players) return best; debug(1, "Denying player request"); @@ -410,22 +423,21 @@ Part *IMuseInternal::allocate_part (byte pri, MidiDriver *midi) { return best; } -int IMuseInternal::getSoundStatus(int sound) { - Player *player = findActivePlayer (sound); - if (player && !player->isFadingOut()) - return 1; - return get_queue_sound_status(sound); -} +int IMuseInternal::getSoundStatus (int sound, bool ignoreFadeouts) { + Player *player; + if (sound == -1) { + player = _players; + for (int i = ARRAYSIZE(_players); i; --i, ++player) { + if (player->isActive() && (!ignoreFadeouts || !player->isFadingOut())) + return player->getID(); + } + return 0; + } -// This is exactly the same as getSoundStatus except that -// it treats sounds that are fading out just the same as -// other sounds. This is the method to use when determining -// what resources to expire from memory. -bool IMuseInternal::get_sound_active(int sound) { - Player *player = findActivePlayer (sound); - if (player) + player = findActivePlayer (sound); + if (player && (!ignoreFadeouts || !player->isFadingOut())) return 1; - return (get_queue_sound_status(sound) != 0); + return get_queue_sound_status(sound); } int IMuseInternal::get_queue_sound_status(int sound) { @@ -1041,6 +1053,17 @@ uint32 IMuseInternal::property(int prop, uint32 value) { case IMuse::PROP_OLD_ADLIB_INSTRUMENTS: _old_adlib_instruments = (value > 0); + break; + + case IMuse::PROP_LIMIT_PLAYERS: + if (value > 0 && value <= ARRAYSIZE(_players)) + _player_limit = (int) value; + break; + + case IMuse::PROP_RECYCLE_PLAYERS: + if (value > 0 && value <= ARRAYSIZE(_players)) + _recycle_players = (value != 0); + break; } return 0; } @@ -1674,8 +1697,8 @@ int IMuse::get_master_volume() { in(); int ret = _target->get_master_volume(); o bool IMuse::startSound(int sound) { in(); bool ret = _target->startSound (sound); out(); return ret; } int IMuse::stopSound(int sound) { in(); int ret = _target->stopSound (sound); out(); return ret; } int IMuse::stop_all_sounds() { in(); int ret = _target->stop_all_sounds(); out(); return ret; } -int IMuse::getSoundStatus(int sound) { in(); int ret = _target->getSoundStatus (sound); out(); return ret; } -bool IMuse::get_sound_active(int sound) { in(); bool ret = _target->get_sound_active (sound); out(); return ret; } +int IMuse::getSoundStatus(int sound) { in(); int ret = _target->getSoundStatus (sound, true); out(); return ret; } +bool IMuse::get_sound_active(int sound) { in(); bool ret = _target->getSoundStatus (sound, false) ? 1 : 0; out(); return ret; } int32 IMuse::doCommand(int a, int b, int c, int d, int e, int f, int g, int h) { in(); int32 ret = _target->doCommand (a,b,c,d,e,f,g,h); out(); return ret; } int IMuse::clear_queue() { in(); int ret = _target->clear_queue(); out(); return ret; } void IMuse::setBase(byte **base) { in(); _target->setBase (base); out(); } diff --git a/scumm/imuse.h b/scumm/imuse.h index bb5c85a3ea..541f34e067 100644 --- a/scumm/imuse.h +++ b/scumm/imuse.h @@ -47,7 +47,9 @@ public: PROP_TEMPO_BASE = 1, PROP_NATIVE_MT32 = 2, PROP_MULTI_MIDI = 3, - PROP_OLD_ADLIB_INSTRUMENTS = 4 + PROP_OLD_ADLIB_INSTRUMENTS = 4, + PROP_LIMIT_PLAYERS = 5, + PROP_RECYCLE_PLAYERS = 6 }; void on_timer (MidiDriver *midi); diff --git a/scumm/imuse_internal.h b/scumm/imuse_internal.h index d035e72267..fc6ce08d6e 100644 --- a/scumm/imuse_internal.h +++ b/scumm/imuse_internal.h @@ -366,6 +366,9 @@ private: int _tempoFactor; + int _player_limit; // Limits how many simultaneous music tracks are played + bool _recycle_players; // Can we stop a player in order to start another one? + uint _queue_end, _queue_pos, _queue_sound; byte _queue_adding; @@ -390,7 +393,7 @@ private: CommandQueue _cmd_queue[64]; DeferredCommand _deferredCommands[4]; - byte *findTag(int sound, char *tag, int index); + byte *findStartOfSound (int sound); bool isMT32(int sound); bool isGM(int sound); int get_queue_sound_status(int sound); @@ -457,8 +460,7 @@ public: bool startSound(int sound); int stopSound(int sound); int stop_all_sounds(); - int getSoundStatus(int sound); - bool get_sound_active(int sound); + int getSoundStatus (int sound, bool ignoreFadeouts = true); int32 doCommand(int a, int b, int c, int d, int e, int f, int g, int h); int clear_queue(); void setBase(byte **base); diff --git a/scumm/imuse_player.cpp b/scumm/imuse_player.cpp index 82255a5763..42cb05bc6f 100644 --- a/scumm/imuse_player.cpp +++ b/scumm/imuse_player.cpp @@ -88,6 +88,14 @@ bool Player::startSound (int sound, MidiDriver *midi) { void *mdhd; int i; + // Not sure what the old code was doing, + // but we'll go ahead and do a similar check. + mdhd = _se->findStartOfSound (sound); + if (!mdhd) { + warning ("Player::startSound(): Couldn't find start of sound %d!", sound); + return false; + } +/* mdhd = _se->findTag(sound, MDHD_TAG, 0); if (mdhd == NULL) { mdhd = _se->findTag(sound, MDPG_TAG, 0); @@ -96,7 +104,7 @@ bool Player::startSound (int sound, MidiDriver *midi) { return false; } } - +*/ _isMT32 = _se->isMT32(sound); _isGM = _se->isGM(sound); @@ -114,8 +122,8 @@ bool Player::startSound (int sound, MidiDriver *midi) { for (i = 0; i < ARRAYSIZE(_parameterFaders); ++i) _parameterFaders[i].init(); - hook_clear(); + if (start_seq_sound(sound) != 0) { _active = false; _midi = NULL; @@ -163,14 +171,16 @@ int Player::start_seq_sound(int sound) { setTempo(500000); setSpeed(128); - ptr = _se->findTag (sound, "MThd", 0); + ptr = _se->findStartOfSound (sound); if (ptr == NULL) return -1; if (_parser) delete _parser; - ptr -= 8; // findTag puts us past the tag and length - _parser = MidiParser::createParser_SMF(); + if (!memcmp (ptr, "FORM", 4)) + _parser = MidiParser::createParser_XMIDI(); + else + _parser = MidiParser::createParser_SMF(); _parser->setTimerRate ((_midi->getBaseTempo() * _speed) >> 7); _parser->setMidiDriver (this); _parser->property (MidiParser::mpSmartJump, 1); diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp index 391d8dece1..fd5fa8a79f 100644 --- a/scumm/scummvm.cpp +++ b/scumm/scummvm.cpp @@ -614,6 +614,10 @@ Scumm::Scumm (GameDetector *detector, OSystem *syst) _imuse->property (IMuse::PROP_OLD_ADLIB_INSTRUMENTS, (_features & GF_SMALL_HEADER) ? 1 : 0); _imuse->property (IMuse::PROP_MULTI_MIDI, detector->_multi_midi); _imuse->property (IMuse::PROP_NATIVE_MT32, detector->_native_mt32); + if (_features & GF_HUMONGOUS) { + _imuse->property (IMuse::PROP_LIMIT_PLAYERS, 1); + _imuse->property (IMuse::PROP_RECYCLE_PLAYERS, 1); + } _imuse->set_music_volume(_sound->_sound_volume_music); } } @@ -815,7 +819,7 @@ void Scumm::initScummVars() { VAR(VAR_VIDEOMODE) = 0x13; VAR(VAR_HEAPSPACE) = 1400; VAR(VAR_MOUSEPRESENT) = true; // FIXME - used to be 0, but that seems odd?!? - if ((_features & GF_HUMONGOUS) && (_gameId != GID_PUTTDEMO)) + if (_features & GF_HUMONGOUS) VAR(VAR_SOUNDPARAM) = 1; // soundblaster for music else VAR(VAR_SOUNDPARAM) = 0; diff --git a/scumm/sound.cpp b/scumm/sound.cpp index bc0bbcb9bb..b52255d673 100644 --- a/scumm/sound.cpp +++ b/scumm/sound.cpp @@ -236,55 +236,8 @@ void Sound::playSound(int soundID) { } // XMIDI else if ((READ_UINT32_UNALIGNED(ptr) == MKID('MIDI')) && (_scumm->_features & GF_HUMONGOUS)) { - // skip HSHD - ptr += 8 + READ_BE_UINT32_UNALIGNED(ptr+12); - if (READ_UINT32_UNALIGNED(ptr) != MKID('SDAT')) - return; // abort - - size = READ_BE_UINT32_UNALIGNED(ptr+4) - 8; - ptr += 8; // don't need SDAT block anymore - - // XMIDI playing stuff goes here - // ptr should be pointing to XMIDI file in memory - // HACK (Jamieson630): Just to see if it works. - static MidiParser *parser = 0; - - MidiDriver *driver = 0; - if (_scumm && _scumm->_imuse) - driver = _scumm->_imuse->getMidiDriver(); - if (driver) { - driver->setTimerCallback (0, 0); - if (parser) { - delete parser; - parser = 0; - } - parser = MidiParser::createParser_XMIDI(); - parser->setMidiDriver (driver); - parser->setTimerRate (driver->getBaseTempo()); - if (_scumm->_gameId != GID_PUTTDEMO) - parser->property (MidiParser::mpAutoLoop, 1); - parser->loadMusic (ptr, size); - driver->open(); - driver->setTimerCallback (parser, &MidiParser::timerCallback); - } - - // FIXME: dumping xmi files for testing, remove when working - if (1) { - File out; - char buf[64]; - sprintf(buf, "dumps/sound-%d.xmi", soundID); - - out.open(buf, "", 1); - if (out.isOpen() == false) { - out.open(buf, "", 2); - if (out.isOpen() == false) - return; - out.write(ptr, size); - } - out.close(); - } - - return; + // Pass XMIDI on to IMuse unprocessed. + // IMuse can handle XMIDI resources now. } else if (READ_UINT32_UNALIGNED(ptr) == MKID('ADL ')) { // played as MIDI, just to make perhaps the later use @@ -636,11 +589,13 @@ int Sound::isSoundRunning(int sound) { return pollCD(); if (_scumm->_features & GF_HUMONGOUS) { - if (sound == -2) { - return isSfxFinished(); - // FIXME are we playing music? - } else if (sound == -1) - return 1; + if (sound == -2) { + return isSfxFinished(); + } else if (sound == -1) { + // getSoundStatus(), with a -1, will return the + // ID number of the first active music it finds. + return _scumm->_imuse->getSoundStatus (sound); + } } _scumm->_mixer->stopID(sound); |